Skip to content

Commit 5fcb221

Browse files
author
Charlie Tonneslan
committed
fix: prevent stack overflow from re-entrant close() in StreamableHTTP transport
Add re-entrancy guard to WebStandardStreamableHTTPServerTransport.close() to prevent RangeError when multiple transports close simultaneously. Clear stream mapping before calling cleanup functions to avoid infinite recursion from cancel callbacks that delete from the mapping or chain to other close operations. Fixes #1699
1 parent ccb78f2 commit 5fcb221

1 file changed

Lines changed: 22 additions & 8 deletions

File tree

packages/server/src/server/streamableHttp.ts

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,7 @@ export class WebStandardStreamableHTTPServerTransport implements Transport {
239239
private _enableDnsRebindingProtection: boolean;
240240
private _retryInterval?: number;
241241
private _supportedProtocolVersions: string[];
242+
private _isClosing = false;
242243

243244
sessionId?: string;
244245
onclose?: () => void;
@@ -887,15 +888,28 @@ export class WebStandardStreamableHTTPServerTransport implements Transport {
887888
}
888889

889890
async close(): Promise<void> {
890-
// Close all SSE connections
891-
for (const { cleanup } of this._streamMapping.values()) {
892-
cleanup();
893-
}
894-
this._streamMapping.clear();
891+
if (this._isClosing) return;
892+
this._isClosing = true;
893+
894+
try {
895+
// Snapshot and clear mapping before cleanup to prevent
896+
// re-entrant deletes from cancel callbacks (fixes #1699)
897+
const entries = [...this._streamMapping.values()];
898+
this._streamMapping.clear();
895899

896-
// Clear any pending responses
897-
this._requestResponseMap.clear();
898-
this.onclose?.();
900+
for (const { cleanup } of entries) {
901+
try {
902+
cleanup();
903+
} catch {
904+
// Suppress errors from already-closed controllers
905+
}
906+
}
907+
908+
// Clear any pending responses
909+
this._requestResponseMap.clear();
910+
} finally {
911+
this.onclose?.();
912+
}
899913
}
900914

901915
/**

0 commit comments

Comments
 (0)