fix: remove dead code after tools throw and fix transport leak on connect error#342
fix: remove dead code after tools throw and fix transport leak on connect error#342matingathani wants to merge 2 commits intostripe:mainfrom
Conversation
…nect error Two bugs fixed: 1. Dead code in stripe-language-model.ts and stripe-language-model-v3.ts Both files threw unconditionally when tools were provided, but then immediately computed unreachable `tools` and `toolChoice` variables. Those dead blocks have been removed. All 327 ai-sdk tests still pass. 2. Transport leak in mcp-client.ts (TypeScript toolkit) In doConnect(), if client.connect() succeeded but listTools() threw, the open MCP connection was abandoned without calling client.close(), leaking the underlying transport indefinitely. Fix: call client.close() before clearing references so the connection is properly torn down on any connect-phase error. All 55 TypeScript toolkit tests still pass.
There was a problem hiding this comment.
Pull request overview
Fixes two bugs across the AI SDK Stripe language model providers and the TypeScript MCP client: removing unreachable tool-handling code paths and ensuring MCP connections are properly closed on connect-phase failures.
Changes:
- Removed unreachable
tools(and related) request-body construction in Stripe language model providers when tool calling is unsupported. - Added connect-error cleanup in
StripeMcpClientto close an established MCP connection before clearing references. - Minor formatting/cleanup in request-body optional parameter handling.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| tools/typescript/src/shared/mcp-client.ts | Closes the MCP client during connect failure cleanup to prevent transport leaks. |
| llm/ai-sdk/provider/stripe-language-model.ts | Removes dead tool/tool-choice request construction after the “tools unsupported” throw. |
| llm/ai-sdk/provider/stripe-language-model-v3.ts | Same dead-code removal for the V3 provider variant. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // Close the active connection before clearing references to avoid leaking | ||
| // the underlying transport if connect() succeeded but listTools() failed. | ||
| try { | ||
| if (this.client) await this.client.close(); | ||
| } catch { | ||
| // Ignore close errors during cleanup | ||
| } | ||
| this.client = null; | ||
| this.transport = null; |
There was a problem hiding this comment.
The new cleanup closes this.client, but there’s no test coverage that close() is invoked when connect() succeeds and listTools() throws. Adding a Jest test that mocks listTools to reject and asserts client.close is awaited (and that connect() rejects with the wrapped error) would prevent regressions of the transport leak fix.
| // Tool calling is not supported by the Stripe AI SDK Provider. | ||
| if (options.tools && options.tools.length > 0) { | ||
| throw new Error( | ||
| 'Tool calling is not supported by the Stripe AI SDK Provider. ' + | ||
| 'The llm.stripe.com API does not currently support function calling or tool use. ' + | ||
| 'Please remove the tools parameter from your request.' | ||
| 'The llm.stripe.com API does not currently support function calling or tool use. ' + | ||
| 'Please remove the tools parameter from your request.' | ||
| ); | ||
| } |
There was a problem hiding this comment.
After removing the toolChoice mapping, options.toolChoice is now silently ignored when options.tools is empty. Since tool calling is explicitly unsupported, it would be clearer/safer to also reject options.toolChoice (or at least warn) and update the error message to mention toolChoice as unsupported, to avoid a behavior change that’s hard for callers to notice.
| @@ -239,38 +240,6 @@ export class StripeLanguageModelV3 implements LanguageModelV3 { | |||
| ); | |||
| } | |||
|
|
|||
There was a problem hiding this comment.
options.toolChoice is no longer forwarded (and is silently ignored) when options.tools is empty. Given the explicit “tool calling not supported” stance, consider explicitly throwing when toolChoice is provided as well (and adjusting the message), so callers don’t think the setting is taking effect.
| if (options.toolChoice !== undefined) { | |
| throw new Error( | |
| 'Tool calling is not supported by the Stripe AI SDK Provider. ' + | |
| 'The llm.stripe.com API does not currently support function calling or tool use. ' + | |
| 'Please remove the toolChoice parameter (and any tools) from your request.' | |
| ); | |
| } |
Changes
Two unrelated bugs fixed in a single PR.
Bug 1 — Dead code after unconditional
throwin language model providersFiles:
llm/ai-sdk/provider/stripe-language-model.ts,llm/ai-sdk/provider/stripe-language-model-v3.tsBoth
getArgs()methods threw unconditionally whenoptions.toolswas non-empty, but the code immediately following thethrowcomputedtoolsandtoolChoicevariables that could never be reached:Fix: Removed the 30–40 lines of unreachable
tools/toolChoicecomputation from both files.Bug 2 — Transport connection leak in TypeScript MCP client
File:
tools/typescript/src/shared/mcp-client.tsIn
doConnect(), ifclient.connect()succeeded but the subsequentclient.listTools()call threw an error, the catch block nulled outthis.clientandthis.transportwithout closing the active connection first, leaking the underlying transport:Fix: Call
await this.client.close()before clearing references so the MCP connection is properly torn down on any connect-phase failure.Testing
llm/ai-sdk: 327 tests passtools/typescript: 55 tests pass