decolua/9router · error · Error

`Device auth initiation failed: ${error}`

Error message

`Device auth initiation failed: ${error}`

What it means

Kilocode's requestDeviceCode treats any non-OK response from POST config.initiateUrl (other than 429) as a fatal initiation failure. The response body text is appended to the message, so the text carries the upstream API's own error detail (auth problems, server errors, malformed requests, outages). This wraps a remote API rejection at the very first step of the device flow.

Source

Thrown at src/lib/oauth/providers/kilocode.js:16

import { KILOCODE_CONFIG } from "../constants/oauth.js";

const kilocode = {
  config: KILOCODE_CONFIG,
  flowType: "device_code",
  requestDeviceCode: async (config) => {
    const response = await fetch(config.initiateUrl, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
    });
    if (!response.ok) {
      if (response.status === 429) {
        throw new Error("Too many pending authorization requests. Please try again later.");
      }
      const error = await response.text();
      throw new Error(`Device auth initiation failed: ${error}`);
    }
    const data = await response.json();
    return {
      device_code: data.code,
      user_code: data.code,
      verification_uri: data.verificationUrl,
      verification_uri_complete: data.verificationUrl,
      expires_in: data.expiresIn || 300,
      interval: 3,
    };
  },
  pollToken: async (config, deviceCode) => {
    const response = await fetch(`${config.pollUrlBase}/${deviceCode}`);
    if (response.status === 202) return { ok: false, data: { error: "authorization_pending" } };
    if (response.status === 403) return { ok: false, data: { error: "access_denied", error_description: "Authorization denied by user" } };
    if (response.status === 410) return { ok: false, data: { error: "expired_token", error_description: "Authorization code expired" } };
    if (!response.ok) return { ok: false, data: { error: "poll_failed", error_description: `Poll failed: ${response.status}` } };
    const data = await response.json();

View on GitHub (pinned to 90b52e06ff)

Solutions

  1. Read the suffix after 'Device auth initiation failed:' — it contains the upstream response body identifying the real cause
  2. Check Kilocode's service status / retry later if the body indicates a 5xx or HTML error page (proxy/outage)
  3. Verify KILOCODE_CONFIG.initiateUrl in src/lib/oauth/constants/oauth.js still matches the current Kilocode API and update it if the API changed
  4. Test basic connectivity from the host: curl -X POST <initiateUrl> — if that fails, fix proxy/firewall/DNS rather than the app
  5. Initiate the device flow again after resolving; the session was never created so nothing to clean up

Example fix

// before
const dc = await requestDeviceCode('kilocode'); // opaque failure on 5xx
// after
try {
  const dc = await requestDeviceCode('kilocode');
} catch (e) {
  const detail = e.message.replace('Device auth initiation failed: ', '');
  console.error('Kilocode initiate failed, upstream said:', detail);
  if (/\d{3}/.test(detail) && /<html|bad gateway|unavailable/i.test(detail)) {
    // upstream/proxy outage — surface retry-later to the user
  }
  throw e;
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Reachability pre-check before starting the flow (best-effort):
async function canReachKilocode() {
  try {
    const r = await fetch(KILOCODE_CONFIG.initiateUrl, { method: 'HEAD' });
    return r.status < 500; // any structured response means the endpoint is reachable
  } catch { return false; }
}

Try / catch

try {
  const dc = await requestDeviceCode('kilocode', challenge);
} catch (e) {
  if (e.message.startsWith('Device auth initiation failed:')) {
    const upstream = e.message.slice('Device auth initiation failed:'.length).trim();
    logger.error('Kilocode initiate rejected by upstream', { upstream });
    // 5xx/HTML body => transient outage/proxy: allow retry later; 4xx body => config/contract problem: alert
  }
  throw e;
}

Prevention

When it happens

Trigger: POST to the Kilocode initiate endpoint returns 4xx/5xx — e.g. Kilocode API outage (5xx), invalid/changed initiateUrl in KILOCODE_CONFIG, network middleware/proxy returning an error page, or API contract changes making the request invalid.

Common situations: Kilocode service incident or maintenance window; corporate proxy intercepting HTTPS and returning 502 HTML; stale constants after a Kilocode API version bump; firewall blocking the request with an error response.

Related errors


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