mastra-ai/mastra · error

result.error (dynamic message from device-login poll failure

Error message

result.error (dynamic message from device-login poll failure)

What it means

The device-login polling loop received a 'failed' result from pollCodexDeviceLogin and the library re-throws the dynamic error message contained in result.error. The message text varies with the underlying poll failure (e.g. token denial, expiry, or an HTTP error from the poll endpoint). It means OpenAI reported the device authorization as definitively failed rather than still pending.

Source

Thrown at mastracode/sdk/src/auth/providers/openai-codex.ts:556

  options.onAuth({
    url: pending.url,
    instructions: pending.instructions,
  });

  await sleep(pending.intervalMs);

  while (true) {
    if (options.signal?.aborted) {
      throw new Error('Login cancelled');
    }

    const result = await pollCodexDeviceLogin(pending, { signal: options.signal });
    if (result.status === 'complete') {
      return result.credentials;
    }
    if (result.status === 'failed') {
      throw new Error(result.error);
    }

    options.onProgress?.('Waiting for OpenAI Codex device authorization...');
    await sleep(result.nextPollMs);
  }
}

/**
 * Login with OpenAI Codex OAuth
 *
 * @param options.onAuth - Called with URL and instructions when auth starts
 * @param options.onPrompt - Called to prompt user for manual code paste (fallback if no onManualCodeInput)
 * @param options.onProgress - Optional progress messages
 * @param options.onManualCodeInput - Optional promise that resolves with user-pasted code.
 *                                    Races with browser callback - whichever completes first wins.
 *                                    Useful for showing paste input immediately alongside browser flow.
 * @param options.originator - OAuth originator parameter (defaults to "mastracode")
 */

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Restart the login flow to get a fresh device code if the previous one expired or was denied.
  2. Complete the authorization promptly — approve in the browser before the code expires.
  3. Inspect result.error's text to distinguish 'denied' vs 'expired' vs HTTP failure and message the user accordingly.
  4. If the error indicates an endpoint/HTTP problem, check network access and OpenAI service status before retrying.

Example fix

// before
try { await loginOpenAICodexDevice({}); } catch (e) { console.error(e); }

// after: restart on denial/expiry
try {
  await loginOpenAICodexDevice({});
} catch (e) {
  if (/denied|expired|slow_down/i.test(e.message)) {
    console.log('Restarting device login...');
    await loginOpenAICodexDevice({});
  } else throw e;
}
Defensive patterns

Strategy: try-catch

Try / catch

try {
  await loginOpenAICodexDevice({});
} catch (e) {
  if (/expired|denied/i.test(e.message)) {
    // fresh code + prompt user to approve quickly
    await loginOpenAICodexDevice({});
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: pollCodexDeviceLogin returns { status: 'failed', error } — typically because the user denied the request, the device code expired before approval, or the poll endpoint returned an unrecoverable error — and loginOpenAICodexDevice throws result.error verbatim.

Common situations: User clicked 'deny' or closed the browser page; user took too long and the device code expired; network hiccup converted to a hard failure by the endpoint; multiple competing login attempts invalidating each other.

Related errors


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/7688f677656a8fdd. Report an issue: GitHub.