Skip to content

Python: Finalize abandoned functional workflow streams without ContextVar leaks - #7798

Open
Shivani . (Shivani767) wants to merge 2 commits into
microsoft:mainfrom
Shivani767:fix/7787-abandoned-functional-stream
Open

Python: Finalize abandoned functional workflow streams without ContextVar leaks#7798
Shivani . (Shivani767) wants to merge 2 commits into
microsoft:mainfrom
Shivani767:fix/7787-abandoned-functional-stream

Conversation

@Shivani767

@Shivani767 Shivani . (Shivani767) commented Aug 20, 2026

Copy link
Copy Markdown

Motivation & Context

Abandoning a functional-workflow ResponseStream mid-iteration (async for event in stream: break) is a normal HITL pattern, but the run generator held both the OpenTelemetry run span and _framework_event_origin() open across yield. Garbage-collecting the generator later injects GeneratorExit from a different Context, so ContextVar.reset raises (Failed to detach context, async generator ignored GeneratorExit).

Description & Review Guide

  • What are the major changes? Functional _run_core now starts the run span unattached (start_workflow_span) and activates it only around _execute. Framework lifecycle events are built inside _framework_event() so the origin token is reset before each yield. _framework_event_origin() also suppresses cross-context reset failures as a last line of defense.
  • What is the impact of these changes? Breaking out of a streaming functional run no longer leaks loop exceptions. Event origin remains FRAMEWORK. Nested processing spans still parent under the run span during _execute. Graph Workflow._run_core is unchanged (same class of OTel attach-across-yield; can be a follow-up).
  • What do you want reviewers to focus on? That we never yield while a ContextVar token is held, and that _activate_span around _execute is enough for nested-span parenting without reintroducing the leak.

Related Issue

Fixes #7787

Contribution Checklist

  • The code builds clean without any errors or warnings
  • All unit tests pass, and I have added new tests where possible
  • The PR follows the Contribution Guidelines
  • This PR is linked to an issue and there is no other open PR for this issue (see Related Issue above).
  • This is not a breaking change. If it is a breaking change, add the breaking change label (or add "[BREAKING]" to the title prefix, before or after any language prefix) — a workflow keeps the label and title prefix in sync automatically.

…tVar leaks

Stop holding the run span and event-origin token across yields so breaking
out of a streaming functional workflow no longer fails during GC.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Prevents ContextVar leaks when functional workflow streams are abandoned.

Changes:

  • Uses unattached workflow spans with scoped activation.
  • Builds framework events before yielding.
  • Adds abandonment and span behavior tests.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
_functional.py Revises functional workflow tracing and event emission.
_events.py Adds safe framework-event construction.
observability.py Adds unattached workflow span creation.
test_functional_workflow.py Adds stream-abandonment regression tests.
test_observability.py Tests unattached span behavior.

💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.

Comment thread python/packages/core/agent_framework/_workflows/_functional.py
Comment thread python/packages/core/tests/workflow/test_functional_workflow.py
Comment thread python/packages/core/agent_framework/_workflows/_functional.py
Reset the run guard in the generator finally so a follow-up run after GC
is allowed, and assert no OpenTelemetry detach errors plus nested-span
parenting under workflow.run.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

python Usage: [Issues, PRs], Target: Python

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Python: [Bug]: Functional workflow ResponseStream leaks ContextVar tokens across tasks when abandoned mid-iteration (break before exhaustion)

2 participants