mastra-ai/mastra · error · ProviderAuthRequiredError
Not logged in to Anthropic.
Error message
Not logged in to Anthropic.
What it means
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.
Source
Thrown at mastracode/sdk/src/providers/claude-max.ts:258
/**
* 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();
if (lower !== 'authorization' && lower !== 'x-api-key') {
headers.set(key, value);
}
});
}View on GitHub (pinned to 75dd419e61)
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
Example fix
// before
const provider = anthropic({ authMode: 'oauth' }); // throws if not logged in
// after
import { ProviderAuthRequiredError } from '...';
try {
return anthropic({ authMode: 'oauth' });
} catch (e) {
if (e instanceof ProviderAuthRequiredError) {
await runOAuthLoginFlow();
return anthropic({ authMode: 'oauth' });
}
throw e;
} Defensive patterns
Strategy: try-catch
Validate before calling
storage.reload();
const token = await storage.getApiKey('anthropic');
if (!token) throw new Error('Run the Anthropic OAuth login before using claude-max.'); Type guard
async function hasAnthropicOAuth(storage: AuthStorage): Promise<boolean> {
const cred = storage.get('anthropic');
return cred != null && cred.type !== 'api_key' && (await storage.getApiKey('anthropic')) != null;
} Try / catch
try {
await runAgent();
} catch (err) {
if (err instanceof ProviderAuthRequiredError) {
await promptAnthropicOAuthLogin(); // then retry once
} else throw err;
} Prevention
- 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
When it happens
Trigger: 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')`.
Common situations: 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.
Related errors
- State token has expired
- Redirect URI is required for SSO login
- Token exchange failed: ${error}
- Failed to fetch user info from Clerk
- Invalid state redirect suffix
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/d26f9d7873f7aa6a.
Report an issue: GitHub.