{"record":{"id":"b4d35c2ac17fa3a2","repo":"mastra-ai/mastra","slug":"authentication-for-mcp-server-servername-was-ca","errorCode":null,"errorMessage":"Authentication for MCP server ${serverName} was cancelled.","messagePattern":"Authentication for MCP server (.+?) was cancelled\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"info","filePath":"packages/mcp/src/client/configuration.ts","lineNumber":874,"sourceCode":"  /**\n   * OAuth authorization state of a configured server.\n   *\n   * Returns `undefined` for servers without an authProvider and for servers\n   * that have not attempted a connection yet.\n   */\n  public getServerAuthState(serverName: string): MCPServerAuthState | undefined {\n    return this.mcpClientsById.get(serverName)?.authState;\n  }\n\n  private async runAuthorizationFlow(serverName: string, options?: { timeoutMs?: number }): Promise<void> {\n    // Register the abort controller synchronously, before the first await, so a\n    // cancel/disconnect during the setup phase (discovery, registration, port\n    // binding) can interrupt the flow rather than letting it park on waitForCode.\n    const abortController = new AbortController();\n    this.authAbortControllersByServer.set(serverName, abortController);\n    const throwIfAborted = () => {\n      if (abortController.signal.aborted) {\n        throw new Error(`Authentication for MCP server ${serverName} was cancelled.`);\n      }\n    };\n\n    // Resources acquired during setup that must be released on every exit path.\n    // Tracked here so the single outer finally can tear them down even if a\n    // fallible setup step (session begin, port binding) throws.\n    let provider: MCPOAuthClientProvider | undefined;\n    let sessionStarted = false;\n    let callbackServer: OAuthCallbackServer | undefined;\n\n    // Installed before the first fallible step so the abort-controller entry,\n    // provider session, and callback server never leak on an early throw.\n    try {\n      const config = this.getServerConfig(serverName);\n      const candidateProvider = config.authProvider;\n      if (!(candidateProvider instanceof MCPOAuthClientProvider)) {\n        throw new Error(\n          `Cannot authenticate MCP server ${serverName}: it is not configured with an MCPOAuthClientProvider.`,","sourceCodeStart":856,"sourceCodeEnd":892,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/mcp/src/client/configuration.ts#L856-L892","documentation":"Plain Error thrown by the throwIfAborted checkpoint inside runAuthorizationFlow. When an OAuth authorization flow is started for a server, an AbortController is stored; if cancelAuth (or disconnect) aborts it, subsequent checkpoints throw this message to unwind the flow instead of leaving it waiting on the callback code.","triggerScenarios":"Calling client.cancelAuthentication(serverName) or disconnecting the server while runAuthorizationFlow is mid-flight (during discovery, registration, port binding, or while waiting for the OAuth callback code).","commonSituations":"User cancels a browser-based login; application shuts down or times out an auth attempt; a re-authentication request supersedes an in-progress flow for the same server.","solutions":["Treat this as an expected cancellation: catch it and skip/retry the auth flow rather than treating it as a fault.","If unintentional, audit code paths that call cancelAuth/disconnect for the server during setup.","Restart the authentication flow (call the authenticate/flow method again) once cancellation is no longer desired.","Check for duplicate/overlapping auth flows for the same serverName that may abort each other."],"exampleFix":"// before\nawait client.authenticateServer('github'); // may throw on cancel\n// after\ntry {\n  await client.authenticateServer('github');\n} catch (e) {\n  if ((e as Error).message.includes('was cancelled')) return; // expected cancel\n  throw e;\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"function isAuthCancelled(e: unknown): boolean {\n  return e instanceof Error && e.message.includes('was cancelled');\n}","tryCatchPattern":"try {\n  await client.authenticateServer(serverName);\n} catch (e) {\n  if (isAuthCancelled(e)) return; // user/system cancelled: expected\n  throw e;\n}","preventionTips":["Avoid overlapping auth flows for the same serverName.","Treat cancellation as a normal outcome in UI and shutdown paths.","Only call cancelAuth/disconnect when a flow is genuinely intended to stop.","Surface cancellation state to users so they don't retry mid-cancel."],"tags":["mcp","oauth","abort","cancellation"],"backgroundTag":"operation-aborted","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}