coleam00/Archon · info

Login cancelled

Error message

Login cancelled

What it means

postTokenRequest in packages/core/src/credentials/openai-oauth.ts:175 rethrows caller cancellation as 'Login cancelled'. When the fetch to OPENAI_TOKEN_URL fails and the caller-supplied AbortSignal (the bridge session's abort signal) is aborted, the error is normalized to this message instead of a misleading network error. It means the token exchange/refresh was cancelled, e.g. by cancelOAuth, supersession, or session expiry.

Source

Thrown at packages/core/src/credentials/openai-oauth.ts:175

  operation: 'exchange' | 'refresh',
  signal?: AbortSignal
): Promise<OpenAiTokenResponse> {
  let response: Response;
  try {
    response = await fetch(OPENAI_TOKEN_URL, {
      method: 'POST',
      headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
      body,
      // The 30s ceiling applies ALWAYS — combined with the caller's session
      // signal when present. Without it, a hung token endpoint would leave a
      // bridge login reporting `pending` for the session's full 10-minute TTL.
      signal: signal
        ? AbortSignal.any([signal, AbortSignal.timeout(30_000)])
        : AbortSignal.timeout(30_000),
    });
  } catch (error) {
    if (signal?.aborted) {
      throw new Error('Login cancelled');
    }
    if (error instanceof Error && error.name === 'TimeoutError') {
      throw new Error(`OpenAI token ${operation} request timed out.`);
    }
    throw new Error(
      `OpenAI token ${operation} request failed: ${error instanceof Error ? error.message : String(error)}`
    );
  }
  if (!response.ok) {
    // Strip the error body down to the OAuth `error` code: this message flows
    // into the bridge's session.detail (and on to the browser/CLI), and OpenAI
    // error bodies can carry account identifiers. Never include the raw body.
    const text = await response.text().catch(() => '');
    let errorCode = '';
    try {
      const parsed = JSON.parse(text) as { error?: unknown };
      if (typeof parsed.error === 'string') {
        errorCode = parsed.error;

View on GitHub (pinned to 0773b97458)

Solutions

  1. Nothing to fix — restart the login by calling startOAuth again after any cancellation.
  2. Avoid cancelling a login unless intended; be aware supersession also cancels in-flight token exchanges.
  3. Handle this message/flow in the UI as a normal cancel outcome, not a bug report.
Defensive patterns

Strategy: try-catch

Validate before calling

// Do not proceed when the session's abort signal is already aborted
if (session.abort.signal.aborted) {
  throw new Error('Login already cancelled; start a new one.');
}

Try / catch

try {
  await exchangeOpenAiAuthorizationCode(code, verifier, signal);
} catch (e) {
  if (e instanceof Error && e.message === 'Login cancelled') {
    // Expected outcome of cancelOAuth/supersession/expiry — restart login if desired
    return;
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling cancelOAuth, starting a newer login that supersedes the session, or the session TTL expiring while the OpenAI token exchange fetch is in flight; the aborted fetch rejects and postTokenRequest maps it to 'Login cancelled'.

Common situations: User clicking 'Cancel' during login; a second login attempt superseding the first; a login left idle until TTL expiry while the token exchange was still pending.

Related errors


AI-assisted analysis of coleam00/Archon@0773b97458 (2026-09-01). Data as JSON: /api/errors/fad22a148704b0dc. Report an issue: GitHub.