can1357/oh-my-pi · error · AIError.OAuthError
xAI device-code token polling failed: ${error instanceof Err
Error message
xAI device-code token polling failed: ${error instanceof Error ? error.message : String(error)} What it means
Thrown by pollXAIDeviceToken when the fetch call to the xAI token endpoint fails during device-code polling — network errors, DNS failures, connection resets, or the built-in request timeout. The underlying error is attached as `cause`; an aborted caller signal yields LoginCancelledError instead. Distinguishing this from a 200-with-error payload matters: this is a transport-level failure of one poll iteration.
Source
Thrown at packages/ai/src/registry/oauth/xai-oauth.ts:438
try {
const timeoutSignal = AbortSignal.timeout(TOKEN_REQUEST_TIMEOUT_MS);
response = await fetchImpl(tokenEndpoint, {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
Accept: "application/json",
},
body: new URLSearchParams({
grant_type: "urn:ietf:params:oauth:grant-type:device_code",
client_id: XAI_OAUTH_CLIENT_ID,
device_code: deviceCode,
}),
redirect: "error",
signal: signal ? AbortSignal.any([signal, timeoutSignal]) : timeoutSignal,
});
} catch (error) {
if (signal?.aborted) throw new AIError.LoginCancelledError();
throw new AIError.OAuthError(
`xAI device-code token polling failed: ${error instanceof Error ? error.message : String(error)}`,
{ kind: "polling", provider: "xai", cause: error },
);
}
let payload: unknown;
try {
payload = await response.json();
} catch (error) {
throw new AIError.OAuthError(
`xAI device-code token polling returned invalid JSON: ${
error instanceof Error ? error.message : String(error)
}`,
{ kind: "polling", provider: "xai", status: response.status, cause: error },
);
}
if (response.ok) {View on GitHub (pinned to 9690622007)
Solutions
- Retry the login — polling repeats until the code expires, and a single failed poll is usually transient; restart `omp` login if it aborts.
- Inspect `err.cause` for the root network error (DNS vs TLS vs timeout) and fix accordingly.
- Keep the machine awake and the network stable during the device-authorization window.
- Check proxy/VPN configuration — polls run repeatedly, so intermittent proxy failures surface here.
- If timeouts are frequent on your link, retry from a faster/more stable connection.
Example fix
// before: letting one bad poll kill the flow
const result = await xaiProvider.credentials();
// after: tolerate transient poll failures with backoff
let lastErr: unknown;
for (let attempt = 0; attempt < 3; attempt++) {
try {
return await xaiProvider.credentials();
} catch (err) {
if (err instanceof AIError.LoginCancelledError) throw err;
if (err instanceof AIError.OAuthError && err.kind === "polling") {
lastErr = err;
await Bun.sleep(2000 * (attempt + 1));
continue;
}
throw err;
}
}
throw lastErr; Defensive patterns
Strategy: retry
Validate before calling
// preflight: confirm the token endpoint is reachable before starting the poll loop
const probe = await fetch(tokenEndpoint, { method: "OPTIONS", signal: AbortSignal.timeout(5000) }).catch(() => null);
if (!probe) {
throw new Error("xAI token endpoint unreachable; fix connectivity before device login");
} Try / catch
try {
await xaiProvider.credentials();
} catch (err) {
if (err instanceof AIError.LoginCancelledError) return;
if (err instanceof AIError.OAuthError && err.kind === "polling" && err.cause) {
// one failed poll is usually transient — restart the flow with backoff
logger.warn("xAI token poll transport failure; retrying login", { cause: err.cause });
await Bun.sleep(3000);
return xaiProvider.credentials();
}
throw err;
} Prevention
- Keep the machine awake and the network connected during the device-authorization window.
- On unreliable links, wrap the whole login in a retry-with-backoff wrapper limited to a few attempts.
- Check VPN/proxy stability — repeated polls surface intermittent proxy failures.
- Inspect err.cause to separate DNS/TLS/timeout causes before changing configuration.
When it happens
Trigger: During `credentials` device login, a poll iteration POSTs grant_type=device_code to the token endpoint and fetchImpl rejects: offline, DNS failure, proxy unreachable, TLS reset, or TOKEN_REQUEST_TIMEOUT_MS exceeded; caller's signal not aborted.
Common situations: Network drops mid-login while the user waits to authorize in the browser; laptop sleeping between polls; VPN disconnects; proxy timeouts on long polls; DNS flakiness on repeat poll requests.
Related errors
- xAI device-code request failed: ${error instanceof Error ? e
- Failed to initiate device authorization: ${initiateResponse.
- Kimi device flow timed out
- xAI device-code response was not a JSON object.
- xAI device-code response missing or invalid required fields.
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/64aa4c7a191f3129.
Report an issue: GitHub.