decolua/9router · error · Error
No authorization code received
Error message
No authorization code received
What it means
The Codex callback proxy handler requires an authorization `code` in the redirect query to perform the server-side token exchange. The callback matched a registered session but carried neither `code` nor `error`, so no exchange is possible and the session is marked failed. This prevents storing a broken/partial connection.
Source
Thrown at src/lib/oauth/utils/server.js:221
if (url.pathname !== "/callback" && url.pathname !== "/auth/callback") {
res.writeHead(404);
res.end("Not found");
return;
}
const code = url.searchParams.get("code");
const state = url.searchParams.get("state");
const errorParam = url.searchParams.get("error");
const session = state ? pendingExchanges.get(state) : null;
// Mode A: server-side exchange (session registered)
if (session) {
try {
if (errorParam) {
throw new Error(url.searchParams.get("error_description") || errorParam);
}
if (!code) throw new Error("No authorization code received");
// Lazy import to avoid circular deps
const { exchangeTokens } = await import("../providers.js");
const { createProviderConnection } = await import("@/models");
const tokenData = await exchangeTokens(
"codex",
code,
session.redirectUri,
session.codeVerifier,
state
);
const connection = await createProviderConnection({
provider: "codex",
authType: "oauth",
...tokenData,
expiresAt: tokenData.expiresIn
? new Date(Date.now() + tokenData.expiresIn * 1000).toISOString()View on GitHub (pinned to 90b52e06ff)
Solutions
- Re-run the Codex OAuth flow and let the provider redirect naturally — don't open or refresh the callback URL manually
- Verify the authorize request uses response_type=code and a redirect_uri the provider will append the code to
- Check no browser extension, shortener, or proxy is stripping query parameters on the 127.0.0.1:1455 redirect
- Ensure only one OAuth flow runs at a time so the correct session is matched by state
- If it persists, confirm the provider's registered redirect URI exactly matches the proxy's /callback path
Defensive patterns
Strategy: try-catch
Validate before calling
// Check the callback carries a code before counting on the exchange.
const params = new URL(callbackUrl, 'http://localhost').searchParams;
if (!params.get('code')) {
console.log('Callback had no code param — restart the OAuth flow.');
} Try / catch
const status = getCodexSessionStatus(state);
if (status && status.status === 'error' && status.error === 'No authorization code received') {
// callback reached the proxy without ?code= — restart the flow
} else if (status && status.status === 'error') {
throw new Error(status.error);
} Prevention
- Never open or refresh the callback URL directly in a browser
- Ensure response_type=code and a redirect_uri the provider appends the code to
- Avoid redirect chains or extensions that drop query parameters
- Run one OAuth flow at a time so the state resolves to the right session
- Keep the provider's registered redirect URI identical to the proxy callback path
When it happens
Trigger: startCodexProxy receives /callback or /auth/callback whose `state` resolves to a pendingExchanges session, but url.searchParams.get('code') is null/empty and no `error` param was sent.
Common situations: Someone opened or refreshed the callback URL manually in a browser (no query params); a redirect chain or extension stripped the code query parameter; the provider redirected to the base callback path without appending parameters (redirect_uri/response_type misconfiguration); a stale tab re-hit port 1455 after the original flow already completed and the URL was re-requested without params.
Related errors
- No authorization code received
- url.searchParams.get("error_description") || errorParam
- Kiro tool input must be a JSON object
- No Codex access token available. Please re-authorize the con
- A redeem request id is required to consume a Codex reset cre
AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30).
Data as JSON: /api/errors/e36e63ba991192b6.
Report an issue: GitHub.