docs(bugs): document SSE /api/v1/stream BrokenPipe storm (BUG-003)

This commit is contained in:
2026-04-17 17:48:42 -04:00
parent a10aee282f
commit 257f780d0f

View File

@@ -35,3 +35,32 @@ Active bugs detected during development. Do not fix until noted otherwise.
**Root cause:** `sqlmodel>=0.0.16` was added to `pyproject.toml` but `pip install -e .` had not been re-run in the dev environment. **Root cause:** `sqlmodel>=0.0.16` was added to `pyproject.toml` but `pip install -e .` had not been re-run in the dev environment.
**Fix:** Run `pip install -e ".[dev]"`. Already applied. **Fix:** Run `pip install -e ".[dev]"`. Already applied.
---
## BUG-003 — SSE `/api/v1/stream` proxy BrokenPipe storm
**Detected:** 2026-04-17
**Status:** Open — do not fix, testing first
**Symptom:** The web-dashboard CLI proxy hammers `BrokenPipeError: [Errno 32] Broken pipe` on `GET /api/v1/stream` and answers with 502s. The SSE client reconnects, a handful succeed (200), then the next chunk write fails again:
```
decnet.cli - web proxy error GET /api/v1/stream?token=...: [Errno 32] Broken pipe
decnet.cli - web code 502, message API proxy error: [Errno 32] Broken pipe
...
File "/home/anti/Tools/DECNET/decnet/cli.py", line 790, in _proxy
self.wfile.write(chunk)
BrokenPipeError: [Errno 32] Broken pipe
```
During the failure the proxy also tries to `send_error(502, ...)` on the already-closed socket, producing a second BrokenPipe and a noisy traceback.
**Root cause (suspected, unconfirmed):** the stdlib `http.server`-based proxy in `decnet/cli.py:_proxy` doesn't handle the browser closing the SSE socket cleanly — any `wfile.write(chunk)` after the client disconnects raises `BrokenPipe`, and then the error path itself writes to the dead socket. Upstream uvicorn SSE generator is probably fine; the proxy layer is the fragile piece.
**Fix:** Deferred. Likely options when we get back to it:
- Catch `BrokenPipeError` / `ConnectionResetError` inside `_proxy` and silently close instead of `send_error` (writing headers to a dead socket is always going to fail).
- Replace the threaded stdlib proxy with something that understands streaming and disconnect signals properly.
- Or bypass the proxy for `/api/v1/stream` specifically and let the browser hit the API directly (CORS permitting).
**Impact:** Dashboard SSE is unusable under any real load; the API itself is unaffected.