The Fix
Upgrade to version 0.36.0 or later.
Based on closed Kludex/starlette issue #947 · PR/commit linked
Production note: Most teams hit this during upgrades or environment changes. Roll out with a canary and smoke critical endpoints (health, OpenAPI/docs) before 100%.
@@ -1,9 +1,12 @@
@@ -1,9 +1,12 @@
+from __future__ import annotations
+
import contextlib
Option A — Upgrade to fixed release\nUpgrade to version 0.36.0 or later.\nWhen NOT to use: This fix should not be used if the WebSocket session needs to remain active after close() is called.\n\n
Why This Fix Works in Production
- Trigger: I've cobbled together a small [commit](https://github.com/devxpy/starlette/commit/41907e863220b8b34f6bcc0d8f3a8d1241ded8eb) to make this work. If you're on…
- Mechanism: The background thread created by WebSocketTestSession does not exit when close() is called
- Why the fix works: Addresses the issue where the background thread created by WebSocketTestSession does not exit when close() is called, ensuring proper cleanup during tests. (first fixed release: 0.36.0).
- If left unfixed, the same config can fail only in production (env differences), causing startup failures or partial feature outages.
Why This Breaks in Prod
- The background thread created by WebSocketTestSession does not exit when close() is called
- Production symptom (often without a traceback): I've cobbled together a small [commit](https://github.com/devxpy/starlette/commit/41907e863220b8b34f6bcc0d8f3a8d1241ded8eb) to make this work. If you're on board with this change, I'd love to upstream this.
Proof / Evidence
- GitHub issue: #947
- Fix PR: https://github.com/kludex/starlette/pull/2427
- First fixed release: 0.36.0
- Reproduced locally: No (not executed)
- Last verified: 2026-02-09
- Confidence: 0.85
- Did this fix it?: Yes (upstream fix exists)
- Own content ratio: 0.81
Discussion
High-signal excerpts from the issue thread (symptoms, repros, edge-cases).
“Here is a minimal example for the issue with latest starlette: https://github.com/seanwu1105/starlette-ws-test-issue There is no way to test a long-running WebSocket with TestClient now”
Failure Signature (Search String)
- I've cobbled together a small [commit](https://github.com/devxpy/starlette/commit/41907e863220b8b34f6bcc0d8f3a8d1241ded8eb) to make this work. If you're on board with this change,
Copy-friendly signature
Failure Signature
-----------------
I've cobbled together a small [commit](https://github.com/devxpy/starlette/commit/41907e863220b8b34f6bcc0d8f3a8d1241ded8eb) to make this work. If you're on board with this change, I'd love to upstream this.
Error Message
Signature-only (no traceback captured)
Error Message
-------------
I've cobbled together a small [commit](https://github.com/devxpy/starlette/commit/41907e863220b8b34f6bcc0d8f3a8d1241ded8eb) to make this work. If you're on board with this change, I'd love to upstream this.
What Broke
Tests hang indefinitely because the server does not exit when the WebSocket is closed.
Why It Broke
The background thread created by WebSocketTestSession does not exit when close() is called
Fix Options (Details)
Option A — Upgrade to fixed release Safe default (recommended)
Upgrade to version 0.36.0 or later.
Use when you can deploy the upstream fix. It is usually lower-risk than long-lived workarounds.
Fix reference: https://github.com/kludex/starlette/pull/2427
First fixed release: 0.36.0
Last verified: 2026-02-09. Validate in your environment.
When NOT to Use This Fix
- This fix should not be used if the WebSocket session needs to remain active after close() is called.
Did This Fix Work in Your Case?
Quick signal helps us prioritize which fixes to verify and improve.
Prevention
- Capture the exact failing error string in logs and tests so you can reproduce via a minimal script.
- Pin production dependencies and upgrade only with a reproducible test that hits the failing path.
Version Compatibility Table
| Version | Status |
|---|---|
| 0.36.0 | Fixed |
Related Issues
No related fixes found.
Sources
We don’t republish the full GitHub discussion text. Use the links above for context.