{"record":{"id":"8debb1cc1f5aff7b","repo":"mastra-ai/mastra","slug":"no-code-verifier-found-authorization-flow-may-not","errorCode":null,"errorMessage":"No code verifier found. Authorization flow may not have started properly.","messagePattern":"No code verifier found\\. Authorization flow may not have started properly\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/mcp/src/client/oauth-provider.ts","lineNumber":328,"sourceCode":"      // Default behavior: just log the URL (CLI scenario)\n      console.info(`Authorization required. Please visit: ${authorizationUrl.toString()}`);\n    }\n  }\n\n  /**\n   * Saves a PKCE code verifier before redirecting to authorization.\n   */\n  async saveCodeVerifier(codeVerifier: string): Promise<void> {\n    await this.storage.set('code_verifier', codeVerifier);\n  }\n\n  /**\n   * Loads the PKCE code verifier for validating authorization result.\n   */\n  async codeVerifier(): Promise<string> {\n    const verifier = await this.storage.get('code_verifier');\n    if (!verifier) {\n      throw new Error('No code verifier found. Authorization flow may not have started properly.');\n    }\n    return verifier;\n  }\n\n  /**\n   * Invalidate credentials when server indicates they're no longer valid.\n   */\n  async invalidateCredentials(scope: 'all' | 'client' | 'tokens' | 'verifier'): Promise<void> {\n    switch (scope) {\n      case 'all':\n        await this.storage.delete('tokens');\n        await this.storage.delete('client_info');\n        await this.storage.delete('code_verifier');\n        this._clientInfo = undefined;\n        break;\n      case 'client':\n        await this.storage.delete('client_info');\n        this._clientInfo = undefined;","sourceCodeStart":310,"sourceCodeEnd":346,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/mcp/src/client/oauth-provider.ts#L310-L346","documentation":"Error thrown by MCPOAuthClientProvider.codeVerifier when no PKCE code_verifier is present in storage. The verifier is saved when an authorization session begins (beginAuthorizationSession); codeVerifier() is called later to validate the authorization result, so a missing verifier means the flow never started or its state was lost.","triggerScenarios":"Calling codeVerifier() (directly or via the OAuth callback completion path) before beginAuthorizationSession ran, after storage was cleared, or after the verifier was consumed/invalidated by a previous completion.","commonSituations":"Server restarts or storage resets between starting and completing login; handling the redirect callback in a different process than the one that started the flow; double-invoking the callback handler; manually clearing provider storage.","solutions":["Restart the authorization flow so beginAuthorizationSession generates and stores a fresh code_verifier before handling the callback.","Use the same storage backend and process for starting and completing the flow (do not clear storage in between).","Ensure the callback handler runs only once; guard against duplicate redirects.","Verify the storage adapter (this.storage) is persistent enough for the auth session duration (not ephemeral/in-memory across restarts)."],"exampleFix":"// before\nawait provider.codeVerifier(); // throws if flow not started\n// after\nawait provider.beginAuthorizationSession(); // stores code_verifier\n// ... redirect user, then on callback:\nconst verifier = await provider.codeVerifier();","handlingStrategy":"validation","validationCode":"// check a session is in progress before completing it\nconst sessionActive = await (provider as any).storage?.get?.('code_verifier');\nif (!sessionActive) {\n  // restart the flow instead of calling codeVerifier()\n  await provider.beginAuthorizationSession();\n}","typeGuard":null,"tryCatchPattern":"try {\n  const verifier = await provider.codeVerifier();\n} catch (e) {\n  if (e instanceof Error && e.message.includes('No code verifier')) {\n    await provider.beginAuthorizationSession(); // restart login\n    return;\n  }\n  throw e;\n}","preventionTips":["Always call beginAuthorizationSession before processing any OAuth callback.","Use persistent storage spanning process restarts for the auth session.","Guard callback handlers to run exactly once per session.","Keep the flow start and completion in the same process/storage scope."],"tags":["mcp","oauth","pkce","state","storage"],"backgroundTag":"missing-code-verifier","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}