decolua/9router · error · Error

`Device code request failed: ${error}`

Error message

`Device code request failed: ${error}`

What it means

Thrown by the Kimi OAuth provider when the device-code request — a POST with client_id to the device authorization endpoint — returns a non-2xx response. The upstream error body text is embedded in the message. This is the first step of the device (user_code) login flow, so failure means no device_code/user_code is produced and polling never starts.

Source

Thrown at src/lib/oauth/providers/kimi.js:24

const kimi = {
  config: KIMI_CONFIG,
  flowType: "device_code",
  requestDeviceCode: async (config) => {
    const { buildKimiHeaders } = await import("open-sse/config/appConstants.js");
    const deviceId = crypto.randomUUID();
    const headers = {
      "Content-Type": "application/x-www-form-urlencoded",
      Accept: "application/json",
      ...buildKimiHeaders(deviceId),
    };
    const response = await fetch(config.deviceCodeUrl, {
      method: "POST",
      headers,
      body: new URLSearchParams({ client_id: config.clientId }),
    });
    if (!response.ok) {
      const error = await response.text();
      throw new Error(`Device code request failed: ${error}`);
    }
    const data = await response.json();
    const authorizeDeviceUrl = config.authorizeDeviceUrl || "https://www.kimi.com/code/authorize_device";
    return {
      device_code: data.device_code,
      user_code: data.user_code,
      verification_uri: data.verification_uri || authorizeDeviceUrl,
      verification_uri_complete:
        data.verification_uri_complete ||
        `${authorizeDeviceUrl}?user_code=${data.user_code}`,
      expires_in: data.expires_in,
      interval: data.interval || 5,
      _kimiDeviceId: deviceId,
    };
  },
  pollToken: async (config, deviceCode, _codeVerifier, extraData) => {
    const { buildKimiHeaders } = await import("open-sse/config/appConstants.js");
    const deviceId = extraData?._kimiDeviceId;

View on GitHub (pinned to 90b52e06ff)

Solutions

  1. Inspect the embedded error body in the message for the upstream reason (invalid_client, etc.).
  2. Verify config.clientId matches the currently valid Kimi client id.
  3. Confirm the device authorization endpoint URL is correct and reachable (curl the endpoint).
  4. Retry after a short delay if the body indicates rate limiting or a 5xx outage.
Defensive patterns

Strategy: retry

Validate before calling

const res = await fetch(deviceAuthUrl, { method: 'HEAD' });
if (!res.ok && res.status >= 500) throw new Error('Kimi device endpoint unavailable, retry later');

Try / catch

try {
  const dc = await kimiProvider.startDeviceFlow(config);
} catch (e) {
  if (e.message.startsWith('Device code request failed:')) {
    const body = e.message.slice('Device code request failed:'.length);
    // log body; if it indicates rate limit/5xx, retry with backoff, else surface config fix
  } else throw e;
}

Prevention

When it happens

Trigger: The device-code endpoint responds 4xx/5xx: invalid or missing config.clientId, client_id revoked, Kimi service outage, wrong deviceAuthUrl override, or rate limiting.

Common situations: Upstream changed the client_id; provider file edited with a bad authorizeDeviceUrl/deviceAuthUrl override; Kimi API temporarily down; corporate firewall blocking www.kimi.com.

Related errors


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