coleam00/Archon · error
Missing authorization code.
Error message
Missing authorization code.
What it means
Thrown by runOpenAiManualLogin when the pasted OpenAI authorization input parses successfully but contains no authorization `code` parameter. Without the code the PKCE token exchange cannot proceed, so the manual login fails explicitly rather than exchanging nothing.
Source
Thrown at packages/core/src/credentials/oauth-bridge.ts:222
* URL (PKCE), surface it on the session, wait for the pasted redirect URL /
* code via the same `codeDeferred` the Pi manual flows use (so poll(code) and
* abort semantics are identical), then exchange it directly — capturing the
* `id_token` Pi drops. Runs NO local callback server (the #1963 wedge
* pattern); the user pastes the final redirect URL or code back instead.
*/
async function runOpenAiManualLogin(session: OAuthSession): Promise<OpenAiOAuthCredentials> {
const flow = createOpenAiAuthorizeFlow();
session.url = flow.url;
if (session.mode === 'pending') session.mode = 'manual';
session.firstSignal.resolve(true);
// Rejected by abortSession on cancel/supersede/expiry — same as Pi flows.
const input = await session.codeDeferred.promise;
const parsed = parseOpenAiAuthorizationInput(input);
if (parsed.state && parsed.state !== flow.state) {
throw new Error('OAuth state mismatch.');
}
if (!parsed.code) {
throw new Error('Missing authorization code.');
}
// Returns its true type — the loginPromise join is typed as delivery.ts's
// loose `OAuthCredentials`, which this satisfies structurally (no cast).
return exchangeOpenAiAuthorizationCode(parsed.code, flow.verifier, session.abort.signal);
}
/**
* Begin a subscription login for a vendor (anthropic/openai/github-copilot;
* legacy claude/codex/copilot ids accepted). Kicks off the held login —
* Pi's `login()` for anthropic/github-copilot, the Archon-owned PKCE flow for
* openai — and returns once the first signal has populated the URL (manual)
* or user-code (device), or a short timeout elapses.
*/
export async function startOAuth(userId: string, providerId: string): Promise<StartOAuthResult> {
// Expired sessions may also hold a callback server — include them in the
// settle-wait below so the port is free before the new login binds it.
const supersededSettled: Promise<void>[] = sweepExpired();
const provider = normalizeCredentialVendor(providerId);View on GitHub (pinned to 0773b97458)
Solutions
- Complete the OAuth consent in the browser and copy the full final redirect URL including ?code=...
- If the browser showed an authorization error (e.g. access denied), restart the login and approve the request.
- Paste the entire URL — don't trim off query parameters.
- Retry the login if the flow expired; a fresh attempt issues a fresh verifier and code.
Example fix
// before (truncated, no code) https://auth.openai.com/oauth/callback?state=abc // after (complete redirect) https://auth.openai.com/oauth/callback?state=abc&code=xyz
Defensive patterns
Strategy: validation
Validate before calling
import { parseOpenAiAuthorizationInput } from './openai-oauth';
function hasAuthCode(input: string): boolean {
return !!parseOpenAiAuthorizationInput(input).code;
} Try / catch
try {
const creds = await loginPromise;
} catch (e) {
if ((e as Error).message === 'Missing authorization code.') {
// retry the login; paste the complete final redirect URL with ?code=
} else throw e;
} Prevention
- Copy the full final URL after consent completes — it must contain a code query parameter.
- If the browser showed a denial/error redirect, restart the login rather than pasting that URL.
- Don't truncate the callback URL when copying it into the prompt.
- Retry promptly: codes and flows expire; a fresh login mints a fresh code.
When it happens
Trigger: Awaiting session.codeDeferred and receiving input where parseOpenAiAuthorizationInput finds no code: pasting the bare authorization page URL without query params, pasting only the state parameter, pasting an error redirect (?error=access_denied), or pasting unrelated text/an empty line.
Common situations: User copies the callback URL before completing consent (no code yet); authorization was denied so the redirect carries an error instead of a code; pasting the wrong URL entirely; truncating the URL and losing the code query parameter.
Related errors
- OAuth state mismatch.
- OpenAI token ${operation} request timed out.
- OpenAI token ${operation} request failed: ${error instanceof
- OpenAI token ${operation} failed (${response.status})${error
- OpenAI token ${operation} returned a non-JSON response (HTTP
AI-assisted analysis of coleam00/Archon@0773b97458 (2026-09-01).
Data as JSON: /api/errors/88be39c45db22ce3.
Report an issue: GitHub.