# Bug in 'Where'?

**URL:** <https://discuss.kotlinlang.org/t/bug-in-where/30979>\
**Category:** Support\
**Created:** [February 25, 2026, 4:36pm UTC](https://discuss.kotlinlang.org/t/bug-in-where/30979 "2026-02-25T16:36:51Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![man85](https://avatars.discourse-cdn.com/v4/letter/m/b2d939/32.png) [@man85](https://discuss.kotlinlang.org/u/man85)\
**Post date:** [February 25, 2026, 4:36pm UTC](https://discuss.kotlinlang.org/t/bug-in-where/30979/1 "2026-02-25T16:36:51Z")

</div>

```auto
interface TypeSafeService<MARKER : Marker<*>> {
  
    fun <T : Any, F> getObject(
        objClass: KClass<F>
    ): T where F: Marker<T>, F: MARKER
}

interface Marker<T: Any> {
    fun markerType() : KClass<T>
}

```

I need that an `objClass` must implement interface `Marker<T>` and function `getObject(...)` returns for it value of `T`.

Why for this case compilation says `Type parameter cannot have any other bounds if it's bounded by another type parameter` ?

Is it possible to get an error during runtime for this code?

Or are there some new approaches in `Kotlin 2.2.0` to get same result?

**UPD**  
The idea is to have an implementation of `TypeSafeService` that could work only with a specific implementation of a `Marker` interface and with other implementations of `Marker` interfaces should be a compilation error:

```kotlin
import kotlin.reflect.*
interface TypeSafeService<MARKER : Marker<*>> {

    @Suppress("BOUNDS_NOT_ALLOWED_IF_BOUNDED_BY_TYPE_PARAMETER")
    fun <T : Any, F> getObject(
        objClass: KClass<F>
    ): T where F: Marker<T>, F: MARKER
}

class DefaultTypeSafeService<MARKER: Marker<*>> : TypeSafeService<MARKER> {
    @Suppress("BOUNDS_NOT_ALLOWED_IF_BOUNDED_BY_TYPE_PARAMETER")
    override fun <T : Any, F> getObject(objClass: KClass<F>): T where F : Marker<T>, F : MARKER {
        TODO("not implemented")
    }

}

interface Marker<T: Any> {
    fun markerType() : KClass<T>
}

// I need to declare different marker interfaces
// first marker interface:
sealed interface Marker1<T: Any>: Marker<T>
object IntMarker1: Marker1<Int> {
    override fun markerType() = Int::class
}
object StringMarker1: Marker1<String> { override fun markerType() = String::class }

// second marker interface:
sealed interface Marker2<T: Any>: Marker<T>
object IntMarker2: Marker2<Int> {
    override fun markerType() = Int::class
}
object StringMarker2: Marker2<String> { override fun markerType() = String::class }

fun foo() {
    val marker1Service = DefaultTypeSafeService<Marker1<*>>() // could only be used with Marker1
    val marker2Service = DefaultTypeSafeService<Marker2<*>>() // could only be used with Marker2
    
    val int1: Int = marker1Service.getObject(IntMarker1::class) // OK 
    val string1: String = marker1Service.getObject(StringMarker1::class) // OK 
    val int2: Int = marker2Service.getObject(IntMarker2::class) // OK 
    val string2: String = marker2Service.getObject(StringMarker2::class) // OK 
    
    marker1Service.getObject(IntMarker2::class) // this should not be allowed
    marker2Service.getObject(IntMarker1::class) // this should not be allowed
}

```

---

<div class="post-metadata">

**Author:** ![kyay10](https://avatars.discourse-cdn.com/v4/letter/k/c57346/32.png) [@kyay10](https://discuss.kotlinlang.org/u/kyay10)\
**Post date:** [February 25, 2026, 4:43pm UTC](https://discuss.kotlinlang.org/t/bug-in-where/30979/2 "2026-02-25T16:43:36Z")

</div>

It’s a Java interop limitation IIRC. You can suppress the error `@Suppress("BOUNDS_NOT_ALLOWED_IF_BOUNDED_BY_TYPE_PARAMETER")`. In your situation, I think this would suffice, though:

```kotlin
interface TypeSafeService<MARKER : Marker<MARKER>> {
  
    fun <T : MARKER> getObject(
        objClass: KClass<out T>,
        context: EvaluationContext? = null
    ): T
}

interface Marker<out T: Any> {
    fun markerType() : KClass<out T>
}

```

---

<div class="post-metadata">

**Author:** ![man85](https://avatars.discourse-cdn.com/v4/letter/m/b2d939/32.png) [@man85](https://discuss.kotlinlang.org/u/man85)\
**Post date:** [February 25, 2026, 4:55pm UTC](https://discuss.kotlinlang.org/t/bug-in-where/30979/3 "2026-02-25T16:55:57Z")

</div>

But in this case:

```auto
interface TypeSafeService<MARKER : Marker<MARKER>> {
  
    fun <T : MARKER> getObject(
        objClass: KClass<out T>,
        context: EvaluationContext? = null
    ): T
}

interface Marker<out T: Any> {
    fun markerType() : KClass<out T>
}

```

I can’t use one implementation `TypeSafeService` with different `Marker` implementation:

```auto
typeSafeServiceImpl.getObj(Marker<Int>::class)
typeSafeServiceImpl.getObj(Marker<Boolean>::class)

```

---

<div class="post-metadata">

**Author:** ![kyay10](https://avatars.discourse-cdn.com/v4/letter/k/c57346/32.png) [@kyay10](https://discuss.kotlinlang.org/u/kyay10)\
**Post date:** [February 25, 2026, 5:11pm UTC](https://discuss.kotlinlang.org/t/bug-in-where/30979/4 "2026-02-25T17:11:51Z")

</div>

Do you have a better example for what usage looks like? In particular, what’s the purpose of `MARKER` as a type parameter?

If I understand your use case right, here’s a version that works pretty well:

```kotlin
import kotlin.reflect.*
interface TypeSafeService {
    fun <F : Marker<T>, T: Any> getObj(objClass: KClass<F>): T
}

inline fun <reified F: Marker<T>, T: Any> TypeSafeService.getObj(): T = getObj(F::class)

interface Marker<T: Any> {
    val markerType : KClass<T>
}

object IntMarker: Marker<Int> { override val markerType = Int::class }
object StringMarker: Marker<String> { override val markerType = String::class }

fun foo(typeSafeServiceImpl: TypeSafeService) {
    typeSafeServiceImpl.getObj<IntMarker, _>()
	typeSafeServiceImpl.getObj<StringMarker, _>()
}

```

---

<div class="post-metadata">

**Author:** ![man85](https://avatars.discourse-cdn.com/v4/letter/m/b2d939/32.png) [@man85](https://discuss.kotlinlang.org/u/man85)\
**Post date:** [February 25, 2026, 6:08pm UTC](https://discuss.kotlinlang.org/t/bug-in-where/30979/5 "2026-02-25T18:08:05Z")

</div>

> [@kyay10](#):
>
> Do you have a better example for what usage looks like?

Sorry, I missed some details. The idea is to have an implementation of `TypeSafeService` that could work only with a specific implementation of a `Marker` interface and with other implementations of `Marker` interfaces should be a compilation error:

```kotlin
import kotlin.reflect.*
interface TypeSafeService<MARKER : Marker<*>> {

    @Suppress("BOUNDS_NOT_ALLOWED_IF_BOUNDED_BY_TYPE_PARAMETER")
    fun <T : Any, F> getObject(
        objClass: KClass<F>
    ): T where F: Marker<T>, F: MARKER
}

class DefaultTypeSafeService<MARKER: Marker<*>> : TypeSafeService<MARKER> {
    @Suppress("BOUNDS_NOT_ALLOWED_IF_BOUNDED_BY_TYPE_PARAMETER")
    override fun <T : Any, F> getObject(objClass: KClass<F>): T where F : Marker<T>, F : MARKER {
        TODO("not implemented")
    }

}

interface Marker<T: Any> {
    fun markerType() : KClass<T>
}

// I need to declare different marker interfaces
// first marker interface:
sealed interface Marker1<T: Any>: Marker<T>
object IntMarker1: Marker1<Int> {
    override fun markerType() = Int::class
}
object StringMarker1: Marker1<String> { override fun markerType() = String::class }

// second marker interface:
sealed interface Marker2<T: Any>: Marker<T>
object IntMarker2: Marker2<Int> {
    override fun markerType() = Int::class
}
object StringMarker2: Marker2<String> { override fun markerType() = String::class }

fun foo() {
    val marker1Service = DefaultTypeSafeService<Marker1<*>>() // could only be used with Marker1
    val marker2Service = DefaultTypeSafeService<Marker2<*>>() // could only be used with Marker2
    
    val int1: Int = marker1Service.getObject(IntMarker1::class) // OK 
    val string1: String = marker1Service.getObject(StringMarker1::class) // OK 
    val int2: Int = marker2Service.getObject(IntMarker2::class) // OK 
    val string2: String = marker2Service.getObject(StringMarker2::class) // OK 
    
    marker1Service.getObject(IntMarker2::class) // this should not be allowed
    marker2Service.getObject(IntMarker1::class) // this should not be allowed
}

```

---

<div class="post-metadata">

**Author:** ![kyay10](https://avatars.discourse-cdn.com/v4/letter/k/c57346/32.png) [@kyay10](https://discuss.kotlinlang.org/u/kyay10)\
**Post date:** [February 25, 2026, 6:32pm UTC](https://discuss.kotlinlang.org/t/bug-in-where/30979/6 "2026-02-25T18:32:34Z")

</div>

Thanks for the example!

I’m not sure if there’s a workaround for the code in its current form other than the suppress. However, you can massage it a bit by introducing a second type parameter:

```kotlin
import kotlin.reflect.*
interface TypeSafeService<MARKER_TYPE> {

    fun <T : Any, F: Marker<T, MARKER_TYPE>> getObject(objClass: KClass<F>): T
}

class DefaultTypeSafeService<MARKER_TYPE> : TypeSafeService<MARKER_TYPE> {
    override fun <T : Any, F: Marker<T, MARKER_TYPE>> getObject(objClass: KClass<F>): T {
        TODO("not implemented")
    }

}

interface Marker<T: Any, MARKER_TYPE> {
    fun markerType() : KClass<T>
    // if you want, you can have extra methods on MARKER_TYPE that can be accessed safely
    // val extra: MARKER_TYPE
}

// I need to declare different marker interfaces
// first marker interface:
sealed interface Marker1<T: Any>: Marker<T, Marker1.Companion> {
    companion object
}
object IntMarker1: Marker1<Int> {
    override fun markerType() = Int::class
}
object StringMarker1: Marker1<String> { override fun markerType() = String::class }

// second marker interface:
sealed interface Marker2<T: Any>: Marker<T, Marker2.Companion> {
    companion object
}
object IntMarker2: Marker2<Int> {
    override fun markerType() = Int::class
}
object StringMarker2: Marker2<String> { override fun markerType() = String::class }

fun foo() {
    val marker1Service = DefaultTypeSafeService<Marker1.Companion>() // could only be used with Marker1
    val marker2Service = DefaultTypeSafeService<Marker2.Companion>() // could only be used with Marker2
    
    val int1: Int = marker1Service.getObject(IntMarker1::class) // OK 
    val string1: String = marker1Service.getObject(StringMarker1::class) // OK 
    val int2: Int = marker2Service.getObject(IntMarker2::class) // OK 
    val string2: String = marker2Service.getObject(StringMarker2::class) // OK 
    
    marker1Service.getObject(IntMarker2::class) // this should not be allowed
    marker2Service.getObject(IntMarker1::class) // this should not be allowed
}

```

---

<div class="post-metadata">

**Author:** ![man85](https://avatars.discourse-cdn.com/v4/letter/m/b2d939/32.png) [@man85](https://discuss.kotlinlang.org/u/man85)\
**Post date:** [February 26, 2026, 5:58am UTC](https://discuss.kotlinlang.org/t/bug-in-where/30979/7 "2026-02-26T05:58:11Z")

</div>

> [@kyay10](#):
>
> However, you can massage it a bit by introducing a second type parameter

Thanks a lot!
