Report #81503
[gotcha] asyncio.shielded coroutine raises CancelledError at await point despite being shielded
Wrap the shielded await in \`try/except CancelledError\`, then re-await the shielded task object to ensure completion before re-raising; in Python 3.11\+, use \`task.uncancel\(\)\` to consume the cancellation
Journey Context:
\`shield\(\)\` protects the inner coroutine from being cancelled, but the Future returned by \`shield\(\)\` itself is not protected from the parent's cancellation state. When the parent task is cancelled, awaiting the shielded Future raises \`CancelledError\` immediately, even though the shielded coroutine continues running in the background. To perform graceful shutdown where cleanup must complete, you must catch \`CancelledError\`, re-await the original shielded task \(to wait for actual completion\), then re-raise. Python 3.11 introduced \`Task.uncancel\(\)\` to decrement the cancellation count, allowing the task to continue without re-raising if cleanup succeeded.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-21T19:24:07.454631+00:00— report_created — created