Repository navigation
fix(sse): default crash-guard logger to console.warn, not console - #12042
diegosouzapw merged 1 commit into
Conversation
installProcessCrashGuard() is called with no argument from
apiBridgeServer.ts, liveServer.ts and embedWsProxy.ts. The default was
`log ?? console`, and the swallow path then calls `logger("warn", ...)`.
console is an object, not a function: the first client-abort that
reached the process-level guard threw TypeError: b is not a function
inside the uncaughtException handler and took the whole server down —
observed in production as a crash loop on ECONNRESET during client
aborts.
Bug-injection verified: reverting to `log ?? console` makes the new
no-argument test fail; restoring the function default passes.
Signed-off-by: Minxi Hou <houminxi@gmail.com>
Load test results: OmniRoute under a 90-agent workloadI ran a staged load test against a production OmniRoute instance (podman, The load generator runs real requests through the full local chain Local-layer capacity
Every single failure past 45 concurrent agents is a Two things stand out to me in this data. Peak memory does not move with Two production bugs the load test flushed outBoth were found because the load generator does something real traffic mostly 1. The resource-pressure detector counts reclaimable page cache as memory
The recovery path made it worse. Fix: compute the ratio from the working set ( Before/after on the identical stage-24 load: 10/10 requests rejected with 2. The client-abort guard crashes the process it protects#11556 added Fix is one line, defaulting the logger to Real-upstream runs (context, not the headline)The same harness ran stages 1-45 against real upstreams. Stage 12 was 72/72. Setup notes for anyone reproducing
The full run artifacts (per-request JSONL, 2 s-interval cgroup metrics, |
55e33f3
into
cheaper-inference:release/v3.8.51
…eaper-inference#12042) Real production incident (2026-08-29): the crash guard cheaper-inference#11556 introduced defaulted its logger to `log ?? console` — console is an object, not a function, so a burst of client aborts (ECONNRESET) reaching the process-level guard threw TypeError inside the uncaughtException handler itself and killed the server, twice in three minutes. Fix: default to console.warn.bind(console). Bug-injection round trip confirms the new test fails on the old default and passes on the fix. Existing guard suite stays green: 9/9 (verified together with the new test).
fix(sse): default crash-guard logger to console.warn, not console
Problem
installProcessCrashGuard()is called with no argument fromapiBridgeServer.ts,liveServer.tsandembedWsProxy.ts. The defaultlogger was
log ?? console, and the swallow path callslogger("warn", ...).consoleis an object, not a function, so the firstclient abort that reached the process-level guard threw
TypeError: b is not a functioninside theuncaughtExceptionhandler and took the whole serverdown.
Observed in production on 2026-08-29 under load: a burst of client aborts
(ECONNRESET from cancelled streaming requests) hit the guard, the TypeError
killed the process, and systemd restarted it — twice in three minutes
(exit status 7, "uncaughtException: Error: aborted" immediately followed by
"TypeError: b is not a function" in the crash log). The guard introduced by
#11556 to prevent exactly this class of crash had become the crash itself.
Fix
Default the logger to
console.warn.bind(console)— a function — when thecaller passes nothing or a non-function:
Verification
guard, locates the registered handler, feeds it a real ECONNRESET-shaped
error, and asserts the abort is swallowed and logged once (the broken
default throws TypeError right there).
log ?? consolemakes the new testfail; restoring the function default passes.
classification) stays green: 9/9.