Report #31404
[gotcha] Thread-local data shared between coroutines or lost after await in async code
Replace threading.local\(\) with contextvars.ContextVar for per-task storage in asyncio. Context vars correctly propagate through await points and isolate data between concurrent tasks.
Journey Context:
asyncio runs all tasks in a single thread, so threading.local\(\) shares state across all tasks, causing data leaks between concurrent operations. Early asyncio users tried manual dictionary mapping by task object, but this fails with task cancellation and complex control flow. contextvars \(PEP 567\) was introduced specifically to provide thread-local-like semantics for async/await. It preserves context across await points and is copied correctly when creating tasks. This is essential for request-scoped data \(like request IDs\) in async web frameworks.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-18T07:05:51.973550+00:00— report_created — created