upstash/context7 · error
${err.error_description || err.error || "Device token poll…
Error message
${err.error_description || err.error || "Device token poll failed"} What it means
Thrown by pollDeviceToken when the RFC 8628 device-flow token endpoint returns a terminal error code other than the handled authorization_pending, slow_down, access_denied, and expired_token cases. The message is the server-provided error_description or error code, defaulting to 'Device token poll failed'. Terminal OAuth codes like invalid_grant, unsupported_grant_type, or invalid_client land here.
Solutions
- Read the message for the server's error code and fix the underlying cause (e.g. invalid_client → fix client ID configuration)
- Restart the device authorization flow from the beginning to obtain a fresh device code
- Verify the OAuth client is configured to allow the device_code grant type on the provider
- Check for multiple concurrent pollers — a device code can only be redeemed once
Example fix
// before: treating every error as retryable
while (true) { try { return await poll(); } catch { await sleep(5_000); } }
// after: fail fast on terminal errors (thrown) vs handled pending states
const result = await pollDeviceToken(deviceCode);
if (result.status === "pending") await sleep(interval); Defensive patterns
Strategy: try-catch
Validate before calling
// ensure device grant is supported before starting the flow
const meta = await fetchDiscoveryMetadata(issuer);
if (!meta.grant_types_supported?.includes("urn:ietf:params:oauth:grant-type:device_code")) {
throw new Error("Provider does not support the device flow");
} Type guard
function isTerminalDeviceError(code: string): boolean {
return !["authorization_pending", "slow_down", "access_denied", "expired_token"].includes(code);
} Try / catch
try {
const tokens = await pollDeviceToken(deviceCode);
} catch (e) {
console.error(`Device flow failed: ${e.message} — restart the login flow`);
await restartDeviceAuthorization();
} Prevention
- Verify the OAuth client has the device_code grant enabled
- Do not run multiple pollers for the same device code
- Respect the server's interval (and slow_down backoff) while polling
When it happens
Trigger: Polling the device token endpoint and receiving an error body whose `error` field is not one of the four handled values — e.g. invalid_client (misconfigured client ID), invalid_grant (device code rejected), unsupported_grant_type, or a malformed body with an unexpected error string.
Common situations: Client credentials misconfigured on the provider, device code already consumed by another poller, provider protocol deviations, or clock/tenant issues causing the server to reject the grant outright.
Related errors
- err.error_description || err.error || "Device token poll…
- await describeErrorResponse(response, fallback)
- Could not reach : )` : ""}\n
- ( )
- -32001
AI-assisted analysis of upstash/context7@4416fb855b (2026-09-16).
Data as JSON: /api/errors/29e975a25a5ff829.
Report an issue: GitHub.
Appendix: source
Thrown at packages/cli/src/utils/auth.ts:312
const err = (await response.json().catch(() => ({}))) as TokenErrorResponse;
return {
status: "transient",
errorMessage: err.error_description || err.error || `HTTP ${response.status}`,
};
}
const err = (await response.json().catch(() => ({}))) as TokenErrorResponse;
switch (err.error) {
case "authorization_pending":
return { status: "pending" };
case "slow_down":
return { status: "slow_down" };
case "access_denied":
return { status: "denied" };
case "expired_token":
return { status: "expired" };
default:
throw new Error(err.error_description || err.error || "Device token poll failed");
}
}
View on GitHub (pinned to 4416fb855b)