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

  1. Read the message for the server's error code and fix the underlying cause (e.g. invalid_client → fix client ID configuration)
  2. Restart the device authorization flow from the beginning to obtain a fresh device code
  3. Verify the OAuth client is configured to allow the device_code grant type on the provider
  4. 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

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


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)