Skip to content

OpenTelemetry contextvars leak across asynchronous generator boundaries in BaseAgent and Runner #5722

Closed

Description

@chriskinzel

Description

In Python asyncio, OpenTelemetry's default context propagation (tracer.start_as_current_span) relies on contextvars. In BaseAgent.run_async and Runner._run_with_trace, OpenTelemetry spans are created around asynchronous generator blocks (async for event in agen: yield event).

When multiple sub-agent coroutines yield and resume concurrently inside an asyncio.TaskGroup, contextvars can leak across coroutine boundaries if the OpenTelemetry span context is not explicitly detached before yielding. This causes child spans from one worker task to be incorrectly parented to the active span of a concurrent sibling task.

Proposed Solution

Explicitly manage OpenTelemetry context attachment and detachment around generator yield boundaries using context.attach and context.detach:

from opentelemetry import context, trace

span = tracer.start_span("invocation")
token = context.attach(trace.set_span_in_context(span))
try:
    # ...
    async for event in agen:
        context.detach(token)
        try:
            yield event
        finally:
            token = context.attach(trace.set_span_in_context(span))
finally:
    context.detach(token)
    span.end()

Activity

  1. added
    tracing[Component] This issue is related to OpenTelemetry tracing
    on May 18, 2026
  2. surajksharma07 commented on May 18, 2026

    @surajksharma07
    Collaborator

    @chriskinzel explicitly managing context.attach/detach around yield boundaries is the right fix here.

    One thing to validate though: context.detach() can throw ValueError when a task is cancelled mid-execution, which is actually why a similar approach was rolled back previously.

    Could you confirm that #5725 wraps those detach calls in try/except ValueError and test it under both the parallel execution and task cancellation scenarios?

    A thorough test pass before raising the PR for review would be ideal!

  3. surajksharma07 commented on May 29, 2026

    @surajksharma07
    Collaborator

    @chriskinzel Going ahead and closing this out since there's been no follow-up in 2 weeks — just wanted to flag that the ValueError concern from my earlier comment turned out to be well-founded: the same context.attach/detach approach was actually applied internally (commit 60b9073) and then reverted two days later (ce113a8) because of exactly that cancellation edge case.

    So #5725 will need to handle that scenario carefully before it's in a state to land without hitting the same revert — specifically, wrapping detach calls in try/except ValueError and verifying behavior when a task is cancelled mid-yield.

    Feel free to reopen once #5725 has that covered and you've run it through the cancellation + parallel execution scenarios — happy to help push it over the line at that point!

  4. added a commit that references this issue on Aug 19, 2026
    bb86bdd
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

request clarification[Status] The maintainer need clarification or more information from the authortracing[Component] This issue is related to OpenTelemetry tracing

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions