decolua/9router · error · Error

`Grok CLI device code request failed: ${error}`

Error message

`Grok CLI device code request failed: ${error}`

What it means

Grok CLI device-flow bootstrap: the POST to xAI's device-code endpoint returned a non-2xx status; the body text is thrown inside this Error. The device flow cannot start — no device_code or verification_uri is produced and polling never begins.

Source

Thrown at src/lib/oauth/providers/grok-cli.js:28

      client_id: config.clientId,
      scope: config.scope,
    });
    // Official CLI sends referrer=grok-build
    if (config.referrer) body.set("referrer", config.referrer);

    const response = await fetch(config.deviceCodeUrl, {
      method: "POST",
      headers: {
        "Content-Type": "application/x-www-form-urlencoded",
        Accept: "application/json",
        "User-Agent": "grok-pager/0.2.93 grok-shell/0.2.93 (linux; x86_64)",
      },
      body,
    });

    if (!response.ok) {
      const error = await response.text();
      throw new Error(`Grok CLI device code request failed: ${error}`);
    }

    return await response.json();
  },
  pollToken: async (config, deviceCode) => {
    const response = await fetch(config.tokenUrl, {
      method: "POST",
      headers: {
        "Content-Type": "application/x-www-form-urlencoded",
        Accept: "application/json",
        "User-Agent": "grok-pager/0.2.93 grok-shell/0.2.93 (linux; x86_64)",
      },
      body: new URLSearchParams({
        grant_type: "urn:ietf:params:oauth:grant-type:device_code",
        device_code: deviceCode,
        client_id: config.clientId,
      }),
    });

View on GitHub (pinned to 90b52e06ff)

Solutions

  1. Read the body text for status-specific causes (invalid client vs rate limit vs 404).
  2. Verify the xAI device-code URL and client_id against the current grok-cli upstream.
  3. Wait and retry with backoff if the response indicates 429 rate limiting.
  4. Test general reachability of the xAI endpoint (curl) to rule out proxy/DNS issues.

Example fix

// before
if (!response.ok) {
  const error = await response.text();
  throw new Error(`Grok CLI device code request failed: ${error}`);
}
// after
if (!response.ok) {
  const error = await response.text();
  throw new Error(`Grok CLI device code request failed (HTTP ${response.status}): ${error}`);
}
Defensive patterns

Strategy: retry

Validate before calling

// Precheck before requesting a device code
if (!config.clientId) throw new Error("Grok CLI client_id missing");
const reachable = await fetch(config.deviceCodeUrl, { method: "OPTIONS" })
  .then(r => r.status < 500).catch(() => false);
if (!reachable) throw new Error("xAI device-code endpoint unreachable");

Type guard

function hasValidGrokDeviceCode(v) {
  return !!v && typeof v === "object" &&
    typeof v.device_code === "string" &&
    (typeof v.verification_uri === "string" || typeof v.verification_url === "string");
}

Try / catch

try {
  const dc = await grokProvider.startDeviceFlow();
} catch (err) {
  if (String(err.message).includes("Grok CLI device code request failed")) {
    if (String(err.message).includes("429")) {
      await waitMs(30_000); // rate limited — back off before retrying
    }
    await retryWithBackoff(() => grokProvider.startDeviceFlow(), { retries: 3 });
  } else throw err;
}

Prevention

When it happens

Trigger: Calling startDeviceFlow for grok-cli when the device-code endpoint replies !response.ok — 401/403 bad client_id, 404 after xAI endpoint changes, 429 rate limit from repeated logins, or network/proxy failures returning error pages.

Common situations: xAI relocated or gated the device endpoint; stale client_id in provider config; aggressive retry loops hitting 429; corporate proxy blocking the domain; xAI outage.

Related errors


AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30). Data as JSON: /api/errors/38c80d169b8e6010. Report an issue: GitHub.