mastra-ai/mastra · error

Anthropic API key credential is configured, but OAuth is req

Error message

Anthropic API key credential is configured, but OAuth is required.

What it means

The Anthropic provider in OAuth (Claude Max/Pro subscription) mode builds a fetch wrapper that reads credentials from the auth storage. If the stored credential is of type 'api_key' but the provider is configured to require OAuth, this hard error is thrown rather than silently falling back. It surfaces a configuration conflict between credential type and auth mode.

Source

Thrown at mastracode/sdk/src/providers/claude-max.ts:253

      return params;
    },
  };
}

/**
 * Build a fetch function that handles Anthropic OAuth.
 * Preserves non-auth headers from init (critical for gateway auth header to survive
 * when used with the gateway). Strips `authorization` and `x-api-key`.
 */
export function buildAnthropicOAuthFetch(opts: { authStorage?: CredentialStore } = {}): typeof fetch {
  return (async (url: string | URL | Request, init?: Parameters<typeof fetch>[1]) => {
    const storage = opts.authStorage ?? getAuthStorage();
    storage.reload();

    const storedCred = storage.get('anthropic');
    if (storedCred?.type === 'api_key') {
      throw new Error('Anthropic API key credential is configured, but OAuth is required.');
    }

    const accessToken = await storage.getApiKey('anthropic');
    if (!accessToken) {
      throw new ProviderAuthRequiredError('Not logged in to Anthropic.');
    }

    // Preserve existing headers, strip auth-related ones
    const headers = new Headers();
    if (init?.headers) {
      const source =
        init.headers instanceof Headers
          ? init.headers
          : Array.isArray(init.headers)
            ? new Headers(init.headers as Array<[string, string]>)
            : new Headers(init.headers as Record<string, string>);
      source.forEach((value, key) => {
        const lower = key.toLowerCase();

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Remove the stored api_key credential and log in via OAuth (e.g. `mastra auth login anthropic` / browser OAuth flow)
  2. Or switch the provider configuration to API-key mode instead of the claude-max OAuth provider
  3. Inspect storage with the auth storage API (`storage.get('anthropic')`) to confirm which credential type is present

Example fix

// before
storage.set('anthropic', { type: 'api_key', apiKey: 'sk-ant-...' });
const provider = claudeMax(); // requires OAuth
// after
storage.remove?.('anthropic');
await loginAnthropicOAuth(); // store { type: 'oauth', ... } then claudeMax() works
Defensive patterns

Strategy: validation

Validate before calling

const cred = storage.get('anthropic');
if (cred?.type === 'api_key') {
  throw new Error('Remove the api_key credential or switch to the API-key provider; OAuth is required.');
}

Type guard

function isOAuthCredential(c: { type: string } | undefined | null): c is { type: 'oauth' } {
  return c?.type === 'oauth';
}

Try / catch

try {
  await runWithAnthropicOAuth();
} catch (err) {
  if (err instanceof Error && err.message.includes('OAuth is required')) {
    // remove api_key credential and re-login via OAuth
  } else throw err;
}

Prevention

When it happens

Trigger: Using the claude-max/anthropic OAuth provider path (`anthropic` or `fetchWithOAuth`) while an Anthropic API key was saved via auth storage (e.g. `mastra auth` or login with an API key), or manually placing an api_key credential in storage.

Common situations: Developer previously authenticated with a standard Anthropic API key, then switched to Claude Max subscription usage; CI machine has ANTHROPIC_API_KEY persisted into storage; mixing team setups where one member logged in with a key and another with OAuth.

Related errors


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