mastra-ai/mastra · error
State mismatch
Error message
State mismatch
What it means
During the browser-callback OAuth login, the user-supplied manual authorization input carried a state parameter that does not match the state this login session generated. The library compares parsed.state against the session state to prevent CSRF / authorization-code injection. A mismatch means the pasted code or redirect URL belongs to a different login attempt and is rejected.
Source
Thrown at mastracode/sdk/src/auth/providers/openai-codex.ts:646
manualError = err instanceof Error ? err : new Error(String(err));
server.cancelWait();
});
const result = await server.waitForCode();
// If manual input was cancelled, throw that error
if (manualError) {
throw manualError;
}
if (result?.code) {
// Browser callback won
code = result.code;
} else if (manualCode) {
// Manual input won (or callback timed out and user had entered code)
const parsed = parseAuthorizationInput(manualCode);
if (parsed.state && parsed.state !== state) {
throw new Error('State mismatch');
}
code = parsed.code;
}
// If still no code, wait for manual promise to complete and try that
if (!code) {
await manualPromise;
if (manualError) {
throw manualError;
}
if (manualCode) {
const parsed = parseAuthorizationInput(manualCode);
if (parsed.state && parsed.state !== state) {
throw new Error('State mismatch');
}
code = parsed.code;
}
}View on GitHub (pinned to 75dd419e61)
Solutions
- Re-run the login and paste the redirect URL from the browser tab opened by THIS run (check the state query param matches).
- Close stale browser tabs from earlier login attempts before retrying.
- If multiple logins run concurrently, serialize them or use separate sessions.
- If you control the flow, log the expected state so users can verify before pasting.
Example fix
// before: pasting an old URL
const input = 'http://localhost:1455/auth/callback?code=OLD&state=OLD_STATE';
await loginOpenAICodex({ onPrompt: () => input });
// after: use the URL from the current attempt
const currentUrl = 'http://localhost:1455/auth/callback?code=NEW&state=CURRENT_STATE';
await loginOpenAICodex({ onPrompt: () => currentUrl }); Defensive patterns
Strategy: validation
Validate before calling
function statesMatch(pastedUrl: string, expectedState: string): boolean {
const state = new URL(pastedUrl).searchParams.get('state');
return !state || state === expectedState;
}
// check before passing input to the login call/prompt Try / catch
try {
await loginOpenAICodex({ onPrompt });
} catch (e) {
if (e.message === 'State mismatch') {
console.error('Pasted URL is from a different login session. Restart and use the current URL.');
} else throw e;
} Prevention
- Paste redirect URLs only from the browser tab of the current attempt.
- Close stale login tabs before re-running login.
- Never run two login sessions concurrently in the same environment.
- Compare the state query param to the expected state before submitting.
When it happens
Trigger: In loginOpenAICodex, the manual-input branch (parseAuthorizationInput(manualCode)) yields a non-empty parsed.state different from the generated state — e.g. the user pasted a redirect URL from an older/parallel login, or a second login session's URL.
Common situations: Running two `login` commands in parallel and pasting the wrong browser URL; reusing a bookmarked redirect URL from a previous login; copying the callback URL from a stale browser tab after restarting the CLI; misconfigured redirect that points at another app's callback.
Related errors
- Invalid authorization state
- Invalid state token format
- Invalid or tampered state token
- Invalid state token format
- Invalid state token signature
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/da8b6edf782228f6.
Report an issue: GitHub.