mastra-ai/mastra · error

Missing authorization code

Error message

Missing authorization code

What it means

`completeAnthropicLogin` parses the pasted authorization input (full URL, `code#state`, or query string) via `parseAuthorizationInput` before exchanging it for tokens. It throws 'Missing authorization code' when the parsed input contains no authorization code — i.e. the string was empty, whitespace, a URL with no code parameter, or only a state fragment. This is a client-side validation guard so no token request is wasted on an unusable input.

Source

Thrown at mastracode/sdk/src/auth/providers/anthropic.ts:64

    redirect_uri: REDIRECT_URI,
    scope: SCOPES,
    code_challenge: challenge,
    code_challenge_method: 'S256',
    state: verifier,
  });

  return { url: `${AUTHORIZE_URL}?${authParams.toString()}`, verifier };
}

/**
 * Complete an Anthropic login: parse the pasted authorization input
 * (full URL, `code#state`, or query string), validate its state, and exchange
 * it for tokens using the verifier from `startAnthropicLogin()`.
 */
export async function completeAnthropicLogin(input: string, verifier: string): Promise<OAuthCredentials> {
  const { code, state } = parseAuthorizationInput(input);
  if (!code) {
    throw new Error('Missing authorization code');
  }
  if (!state || state !== verifier) {
    throw new Error('Invalid authorization state');
  }

  const tokenResponse = await fetch(TOKEN_URL, {
    method: 'POST',
    // Bound the OAuth exchange so an unresponsive upstream cannot pin the
    // caller (and, in the shipyard server, the containing project lock)
    // indefinitely. See 2025-07-23 shipyard latency incident.
    signal: AbortSignal.timeout(15_000),
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      grant_type: 'authorization_code',
      client_id: CLIENT_ID,
      code,

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Re-prompt the user to copy the complete `code#state` string exactly as displayed on Anthropic's callback page and paste it again.
  2. Check that the pasted input actually contains a code segment (before the `#` for paste format, or a `code=` query param for URL format) before calling the API.
  3. Verify the login was not denied — if Anthropic redirected with ?error=..., the user declined and you should restart with startAnthropicLogin().
  4. Log the raw input (redacted) to confirm what parseAuthorizationInput received.

Example fix

// before
const input = new URL(callbackRedirectUrl).searchParams.get('s') ?? ''; // wrong field, empty
await completeAnthropicLogin(input, verifier); // throws 'Missing authorization code'
// after
const input = new URL(callbackRedirectUrl).searchParams.get('code') ?? '';
if (!input) throw new Error('OAuth redirect did not contain a code — user likely denied access');
await completeAnthropicLogin(input, verifier);
Defensive patterns

Strategy: validation

Validate before calling

function extractCode(input: string): string | null {
  const trimmed = input.trim();
  if (!trimmed) return null;
  try {
    const url = new URL(trimmed);
    return url.searchParams.get('code');
  } catch {
    const [code] = trimmed.split('#');
    return code || null;
  }
}
// before calling: if (!extractCode(input)) re-prompt the user;

Try / catch

try {
  await completeAnthropicLogin(input, verifier);
} catch (e) {
  if (e instanceof Error && e.message === 'Missing authorization code') {
    showPrompt('Paste the full code#state string shown on the authorization page');
    return;
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling completeAnthropicLogin('', verifier), calling it with a URL that lacks the `code` query param (e.g. an error redirect like ?error=access_denied), or prompting the user who pastes only the `#state` portion / presses Enter without pasting anything.

Common situations: User cancels at Anthropic's hosted callback page and copies the URL without a code; clipboard copy only grabbed part of the `code#state` string; the code was already consumed by a prior exchange attempt and stripped; developer passes the raw callback host URL without params in a scripted flow.

Related errors


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