{"record":{"id":"d26f9d7873f7aa6a","repo":"mastra-ai/mastra","slug":"not-logged-in-to-anthropic","errorCode":null,"errorMessage":"Not logged in to Anthropic.","messagePattern":"Not logged in to Anthropic\\.","errorType":"exception","errorClass":"ProviderAuthRequiredError","httpStatus":null,"severity":"error","filePath":"mastracode/sdk/src/providers/claude-max.ts","lineNumber":258,"sourceCode":"\n/**\n * Build a fetch function that handles Anthropic OAuth.\n * Preserves non-auth headers from init (critical for gateway auth header to survive\n * when used with the gateway). Strips `authorization` and `x-api-key`.\n */\nexport function buildAnthropicOAuthFetch(opts: { authStorage?: CredentialStore } = {}): typeof fetch {\n  return (async (url: string | URL | Request, init?: Parameters<typeof fetch>[1]) => {\n    const storage = opts.authStorage ?? getAuthStorage();\n    storage.reload();\n\n    const storedCred = storage.get('anthropic');\n    if (storedCred?.type === 'api_key') {\n      throw new Error('Anthropic API key credential is configured, but OAuth is required.');\n    }\n\n    const accessToken = await storage.getApiKey('anthropic');\n    if (!accessToken) {\n      throw new ProviderAuthRequiredError('Not logged in to Anthropic.');\n    }\n\n    // Preserve existing headers, strip auth-related ones\n    const headers = new Headers();\n    if (init?.headers) {\n      const source =\n        init.headers instanceof Headers\n          ? init.headers\n          : Array.isArray(init.headers)\n            ? new Headers(init.headers as Array<[string, string]>)\n            : new Headers(init.headers as Record<string, string>);\n      source.forEach((value, key) => {\n        const lower = key.toLowerCase();\n        if (lower !== 'authorization' && lower !== 'x-api-key') {\n          headers.set(key, value);\n        }\n      });\n    }","sourceCodeStart":240,"sourceCodeEnd":276,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/mastracode/sdk/src/providers/claude-max.ts#L240-L276","documentation":"Thrown as ProviderAuthRequiredError when the OAuth fetch wrapper for Anthropic finds no stored access token after reloading auth storage. The library cannot attach a Bearer token to Anthropic requests, so it aborts before any network call. This is the 'you must log in' guard of the Claude Max OAuth flow.","triggerScenarios":"Using the anthropic/claude-max OAuth provider (via `anthropic` or `fetchWithOAuth`) with no 'anthropic' entry in auth storage, or the stored credential type is neither 'api_key' nor holds a usable access token returned by `storage.getApiKey('anthropic')`.","commonSituations":"Fresh machine or CI container where `mastra auth login anthropic` was never run; token file deleted or HOME changed; expired/revoked token that storage could not refresh; running in an environment without interactive login capability.","solutions":["Run the OAuth login flow to store an Anthropic access token (e.g. `mastra auth login anthropic` and complete the browser flow)","Verify the auth storage file exists and is readable in the environment (check HOME/XDG paths, CI mounts)","Catch ProviderAuthRequiredError and prompt the user to authenticate before retrying","If non-interactive use is required, configure the API-key provider variant instead"],"exampleFix":"// before\nconst provider = anthropic({ authMode: 'oauth' }); // throws if not logged in\n// after\nimport { ProviderAuthRequiredError } from '...';\ntry {\n  return anthropic({ authMode: 'oauth' });\n} catch (e) {\n  if (e instanceof ProviderAuthRequiredError) {\n    await runOAuthLoginFlow();\n    return anthropic({ authMode: 'oauth' });\n  }\n  throw e;\n}","handlingStrategy":"try-catch","validationCode":"storage.reload();\nconst token = await storage.getApiKey('anthropic');\nif (!token) throw new Error('Run the Anthropic OAuth login before using claude-max.');","typeGuard":"async function hasAnthropicOAuth(storage: AuthStorage): Promise<boolean> {\n  const cred = storage.get('anthropic');\n  return cred != null && cred.type !== 'api_key' && (await storage.getApiKey('anthropic')) != null;\n}","tryCatchPattern":"try {\n  await runAgent();\n} catch (err) {\n  if (err instanceof ProviderAuthRequiredError) {\n    await promptAnthropicOAuthLogin(); // then retry once\n  } else throw err;\n}","preventionTips":["Run the OAuth login as part of environment setup (dev machine and CI)","Check `storage.getApiKey('anthropic')` non-null before instantiating the provider","Mount/persist the auth storage file in containers and CI","Catch ProviderAuthRequiredError at app start to prompt login early"],"tags":["auth","oauth","not-authenticated"],"backgroundTag":"oauth-not-logged-in","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}