Skip to content

fix(client): abort legacy SSE reconnect chain when the originating request times out - #2616

Open
claude[bot] wants to merge 17 commits into
mainfrom
fix/2615-legacy-sse-reconnect-after-timeout
Open

fix(client): abort legacy SSE reconnect chain when the originating request times out#2616
claude[bot] wants to merge 17 commits into
mainfrom
fix/2615-legacy-sse-reconnect-after-timeout

fix(core,client): Gecko-safe timeout timers; keep resume token across…

3b486e8
Select commit
Loading
Failed to load commit list.
Claude / Claude Code Review completed Aug 6, 2026 in 19m 26s

Code review found 4 potential issues

Found 5 candidates, confirmed 4. See review comments for details.

Details

Severity Count
🔴 Important 0
🟡 Nit 1
🟣 Pre-existing 3
Severity File:Line Issue
🟣 Pre-existing packages/client/src/client/streamableHttp.ts:1226-1236 onerror-discipline sweep leaves SSEClientTransport._send catch unguarded: close() mid-POST still surfaces a spurious Abo
🟣 Pre-existing packages/client/src/client/streamableHttp.ts:693-705 Single-slot _cancelReconnection cannot cancel concurrent reconnect chains on close(), and settled requests leave armed t

Annotations

Check notice on line 1236 in packages/client/src/client/streamableHttp.ts

See this annotation in the file changed.

@claude claude / Claude Code Review

onerror-discipline sweep leaves SSEClientTransport._send catch unguarded: close() mid-POST still surfaces a spurious AbortError

Pre-existing issue, outside this diff (anchored here because the actual site sits in a sibling file): `SSEClientTransport._send`'s catch (`packages/client/src/client/sse.ts:409-412`) is the last surviving instance in the client package of the unguarded `this.onerror?.(error); throw error;` catch shape this PR's onerror-discipline sweep replaced. Its POST runs on `signal: this._abortController?.signal` alone and `close()` aborts that controller, so `close()` landing mid-POST on the legacy HTTP+SS

Check notice on line 705 in packages/client/src/client/streamableHttp.ts

See this annotation in the file changed.

@claude claude / Claude Code Review

Single-slot _cancelReconnection cannot cancel concurrent reconnect chains on close(), and settled requests leave armed timers/scheduler tasks

Pre-existing issue at the center of the reconnect-teardown machinery this PR extends: `_cancelReconnection` is a single per-transport slot, but the transport routinely owns multiple concurrent reconnect chains (the standalone notification GET chain plus one per in-flight request), so each `_scheduleReconnection` overwrites the slot and `close()` can disarm only the last-written pending attempt — surviving timers pin a Node process for up to `maxReconnectionDelay` (30s default), and the `Reconnec