# What is the receiver supposed to be in a \`withContext\` block (and an extension function)?

**URL:** <https://discuss.kotlinlang.org/t/what-is-the-receiver-supposed-to-be-in-a-withcontext-block-and-an-extension-function/31031>\
**Category:** Language Design\
**Created:** [April 13, 2026, 10:58am UTC](https://discuss.kotlinlang.org/t/what-is-the-receiver-supposed-to-be-in-a-withcontext-block-and-an-extension-function/31031 "2026-04-13T10:58:22Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![nikclayton](https://avatars.discourse-cdn.com/v4/letter/n/67e7ee/32.png) [@nikclayton](https://discuss.kotlinlang.org/u/nikclayton)\
**Post date:** [April 13, 2026, 10:58am UTC](https://discuss.kotlinlang.org/t/what-is-the-receiver-supposed-to-be-in-a-withcontext-block-and-an-extension-function/31031/1 "2026-04-13T10:58:22Z")

</div>

What is the receiver supposed to be in a `withContext` block in an extension function?

Consider the following example:

```kotlin
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
import java.net.URI

suspend fun URI.foo() = withContext(Dispatchers.IO) {
    println(scheme)
    println(toString())
}

fun main() {
    val u = URI("https://example.com/some/path")
    runBlocking {
        u.foo()
    }
}

```

That prints:

```auto
https
"coroutine#1":DispatchedCoroutine{Active}@d03e0e8

```

In other words, in `URI.foo()`, `println(scheme)` is equvalent to `println(this@foo.scheme)`, but `println(toString())` is equvalent to `println(this.toString())`

I would expect that to:

1: Print

```auto
https
https://example.com/some/path

```

because the receiver is the `URI` the extension function is being called on. I.e., as if the code was:

```kotlin
suspend fun URI.foo() = withContext(Dispatchers.IO) {
    println(this@foo.scheme)
    println(this@foo.toString())
}

```

Or

2: Be a compilation error, because `this` inside the `withContext` block refers to the coroutine, and the coroutine doesn’t have a `scheme` property. I.e., as if the code was:

```kotlin
suspend fun URI.foo() = withContext(Dispatchers.IO) {
    println(this.scheme)
    println(this.toString())
}

```

(which fails to compile with the error “Unresolved reference ‘scheme’”)

---

<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:** [April 13, 2026, 2:50pm UTC](https://discuss.kotlinlang.org/t/what-is-the-receiver-supposed-to-be-in-a-withcontext-block-and-an-extension-function/31031/2 "2026-04-13T14:50:59Z")

</div>

From the [docs](https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/with-context.html):

```kotlin
suspend fun <T> withContext(context: CoroutineContext, block: suspend CoroutineScope.() -> T): T

```

so the receiver is a `CoroutineScope`.  
To access an outer receiver, you can refer to it by the function name `this@foo`. You can also use a function like so:

```kotlin
fun <T> T.receiver(): T = this

```

to be called like `receiver<URI>()` so that you can do it by type

---

<div class="post-metadata">

**Author:** ![nikclayton](https://avatars.discourse-cdn.com/v4/letter/n/67e7ee/32.png) [@nikclayton](https://discuss.kotlinlang.org/u/nikclayton)\
**Post date:** [April 13, 2026, 3:18pm UTC](https://discuss.kotlinlang.org/t/what-is-the-receiver-supposed-to-be-in-a-withcontext-block-and-an-extension-function/31031/3 "2026-04-13T15:18:52Z")

</div>

Yes. But that doesn’t explain why using the bare `scheme` works. Why doesn’t that cause an error in the original code?

---

<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:** [April 13, 2026, 4:14pm UTC](https://discuss.kotlinlang.org/t/what-is-the-receiver-supposed-to-be-in-a-withcontext-block-and-an-extension-function/31031/4 "2026-04-13T16:14:07Z")

</div>

This behaviour exists in Java (I believe) with inner classes.  
Consider the following code:

```kotlin
class Foo {
  fun foo() {}
  fun bar() {}
  inner class Bar {
    fun bar() {}
    fun baz() {
      foo() // uses this@Foo
      bar() // uses this
    }
  }

```

The point is that lexical scoping tells you what declarations are accessible.  
An extension function then acts semantically as-if it was magically written inside the class (but it’s always `final`, has no access to `private` or `protected` declarations beyond what a non-extension function has in the same scope, etc).  
It thus makes sense that multiple receivers would have their declarations accessible.

Digging in the docs, I found [this](https://kotlinlang.org/docs/type-safe-builders.html#scope-control-dslmarker):

> You can call methods of every available [implicit receiver](https://kotlinlang.org/docs/lambdas.html#function-literals-with-receiver) inside a lambda

There’s probably a more helpful docs page about this, I just couldn’t find it quickly.

EDIT: Here’s another [clarification](https://kotlinlang.org/docs/extensions.html#declaring-extensions-as-members) about implicit receivers:

> You can declare extensions for one class inside another. Extensions like this have multiple implicit receivers. An implicit receiver is an object whose members you can access without qualifying them with [`this`](https://kotlinlang.org/docs/this-expressions.html#qualified-this):
> 
> - The class where you declare the extension is the dispatch receiver.
> - The extension function’s receiver type is the extension receiver.

There’s also [this](https://kotlinlang.org/docs/lambdas.html#function-literals-with-receiver), specifically about extension lambdas (but you might need to squint a little to see this as saying that the implicit receiver is available even to nested extension lambdas):

> [Function types](https://kotlinlang.org/docs/lambdas.html#function-types) with receiver, such as `A.(B) -> C`, can be instantiated with a special form of function literals – function literals with receiver.
> 
> As mentioned above, Kotlin provides the ability [to call an instance](https://kotlinlang.org/docs/lambdas.html#invoking-a-function-type-instance) of a function type with receiver while providing the receiver object.
> 
> Inside the body of the function literal, the receiver object passed to a call becomes an implicit `this`, so that you can access the members of that receiver object without any additional qualifiers, or access the receiver object using a [`this` expression](https://kotlinlang.org/docs/this-expressions.html).
> 
> This behavior is similar to that of [extension functions](https://kotlinlang.org/docs/extensions.html), which also allow you to access the members of the receiver object inside the function body.

---

<div class="post-metadata">

**Author:** ![nikclayton](https://avatars.discourse-cdn.com/v4/letter/n/67e7ee/32.png) [@nikclayton](https://discuss.kotlinlang.org/u/nikclayton)\
**Post date:** [April 14, 2026, 8:03am UTC](https://discuss.kotlinlang.org/t/what-is-the-receiver-supposed-to-be-in-a-withcontext-block-and-an-extension-function/31031/5 "2026-04-14T08:03:35Z")

</div>

Thanks, that’s very helpful. I’ve filed [https://youtrack.jetbrains.com/issue/KT-85700/Unqualified-references-in-lambdas-with-multiple-receivers-should-warn-by-default](https://youtrack.jetbrains.com/issue/KT-85700/Unqualified-references-in-lambdas-with-multiple-receivers-should-warn-by-default) to suggest this should be a compiler warning.

---

<div class="post-metadata">

**Author:** ![clovisai](https://avatars.discourse-cdn.com/v4/letter/c/a9adbd/32.png) [@clovisai](https://discuss.kotlinlang.org/u/clovisai)\
**Post date:** [April 20, 2026, 1:27pm UTC](https://discuss.kotlinlang.org/t/what-is-the-receiver-supposed-to-be-in-a-withcontext-block-and-an-extension-function/31031/6 "2026-04-20T13:27:30Z")

</div>

This is an intended feature which powers many (most?) DSLs. If a compiler warning is introduced, many things will break or have spurious warnings.

Context parameters will be stable very soon and do not have this ambiguity. However, replacing extension functions by context parameters is a breaking change, so it won’t happen for existing methods like `withContext`.
