fix(client): abort legacy SSE reconnect chain when the originating request times out - #2616
Open
claude[bot] wants to merge 17 commits into
Open
fix(client): abort legacy SSE reconnect chain when the originating request times out#2616claude[bot] wants to merge 17 commits into
claude[bot] wants to merge 17 commits into
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
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
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
Loading