mastra-ai/mastra · error · Error

No code verifier found. Authorization flow may not have star

Error message

No code verifier found. Authorization flow may not have started properly.

What it means

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.

Source

Thrown at packages/mcp/src/client/oauth-provider.ts:328

      // Default behavior: just log the URL (CLI scenario)
      console.info(`Authorization required. Please visit: ${authorizationUrl.toString()}`);
    }
  }

  /**
   * Saves a PKCE code verifier before redirecting to authorization.
   */
  async saveCodeVerifier(codeVerifier: string): Promise<void> {
    await this.storage.set('code_verifier', codeVerifier);
  }

  /**
   * Loads the PKCE code verifier for validating authorization result.
   */
  async codeVerifier(): Promise<string> {
    const verifier = await this.storage.get('code_verifier');
    if (!verifier) {
      throw new Error('No code verifier found. Authorization flow may not have started properly.');
    }
    return verifier;
  }

  /**
   * Invalidate credentials when server indicates they're no longer valid.
   */
  async invalidateCredentials(scope: 'all' | 'client' | 'tokens' | 'verifier'): Promise<void> {
    switch (scope) {
      case 'all':
        await this.storage.delete('tokens');
        await this.storage.delete('client_info');
        await this.storage.delete('code_verifier');
        this._clientInfo = undefined;
        break;
      case 'client':
        await this.storage.delete('client_info');
        this._clientInfo = undefined;

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Restart the authorization flow so beginAuthorizationSession generates and stores a fresh code_verifier before handling the callback.
  2. Use the same storage backend and process for starting and completing the flow (do not clear storage in between).
  3. Ensure the callback handler runs only once; guard against duplicate redirects.
  4. Verify the storage adapter (this.storage) is persistent enough for the auth session duration (not ephemeral/in-memory across restarts).

Example fix

// before
await provider.codeVerifier(); // throws if flow not started
// after
await provider.beginAuthorizationSession(); // stores code_verifier
// ... redirect user, then on callback:
const verifier = await provider.codeVerifier();
Defensive patterns

Strategy: validation

Validate before calling

// check a session is in progress before completing it
const sessionActive = await (provider as any).storage?.get?.('code_verifier');
if (!sessionActive) {
  // restart the flow instead of calling codeVerifier()
  await provider.beginAuthorizationSession();
}

Try / catch

try {
  const verifier = await provider.codeVerifier();
} catch (e) {
  if (e instanceof Error && e.message.includes('No code verifier')) {
    await provider.beginAuthorizationSession(); // restart login
    return;
  }
  throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/8debb1cc1f5aff7b. Report an issue: GitHub.