Summary
Sentry recorded recurring orb_broker_unavailable: Orb broker token exchange failed (500). events (79 occurrences over 6 days) on the self-hosted deployment's calls to the central Orb broker.
Root cause
readOrbRelayRegisterBody (src/orb/relay.ts) reads the incoming request body via a ReadableStream reader. It's called at all three of its route call sites (POST /v1/orb/token, /v1/orb/relay/register, /v1/orb/relay pull) before each route's own try/catch block. A dropped connection or network reset mid-read throws uncaught out of this function, escaping as a bare framework 500 instead of the route's own clean 4xx/503 JSON error response.
Fix
Wrap the read loop in readOrbRelayRegisterBody and return null on any stream error — the same sentinel already used uniformly by all three callers for "payload too large." Single-point fix at the source function rather than wrapping each call site separately.
Validation
npm run typecheck
npx vitest run test/integration/orb-relay.test.ts — added a regression test constructing a ReadableStream that enqueues a partial chunk then errors (simulating a realistic mid-read network drop).
Summary
Sentry recorded recurring
orb_broker_unavailable: Orb broker token exchange failed (500).events (79 occurrences over 6 days) on the self-hosted deployment's calls to the central Orb broker.Root cause
readOrbRelayRegisterBody(src/orb/relay.ts) reads the incoming request body via aReadableStreamreader. It's called at all three of its route call sites (POST /v1/orb/token,/v1/orb/relay/register,/v1/orb/relaypull) before each route's own try/catch block. A dropped connection or network reset mid-read throws uncaught out of this function, escaping as a bare framework 500 instead of the route's own clean 4xx/503 JSON error response.Fix
Wrap the read loop in
readOrbRelayRegisterBodyand returnnullon any stream error — the same sentinel already used uniformly by all three callers for "payload too large." Single-point fix at the source function rather than wrapping each call site separately.Validation
npm run typechecknpx vitest run test/integration/orb-relay.test.ts— added a regression test constructing aReadableStreamthat enqueues a partial chunk then errors (simulating a realistic mid-read network drop).