can1357/oh-my-pi · error · AIError.OAuthError

Failed to initiate device authorization: ${initiateResponse.

Error message

Failed to initiate device authorization: ${initiateResponse.status}

What it means

Kilo device-authorization initiation failed with any status other than 2xx and other than 429 (which has its own message). loginKilo wraps the HTTP status into this OAuthError with kind "device-auth" so the caller knows the login could not even start. The status field on the error carries the actual HTTP response code.

Source

Thrown at packages/ai/src/registry/kilo.ts:35

	token?: string;
}

export async function loginKilo(callbacks: OAuthController): Promise<OAuthCredentials> {
	const fetchImpl = callbacks.fetch ?? fetch;
	const initiateResponse = await fetchImpl(`${KILO_DEVICE_AUTH_BASE_URL}/codes`, {
		method: "POST",
		headers: { "Content-Type": "application/json" },
	});

	if (!initiateResponse.ok) {
		if (initiateResponse.status === 429) {
			throw new AIError.OAuthError("Too many pending authorization requests. Please try again later.", {
				kind: "polling",
				provider: "kilo",
				status: initiateResponse.status,
			});
		}
		throw new AIError.OAuthError(`Failed to initiate device authorization: ${initiateResponse.status}`, {
			kind: "device-auth",
			provider: "kilo",
			status: initiateResponse.status,
		});
	}

	const initiateData = (await initiateResponse.json()) as KiloDeviceAuthCodeResponse;
	const userCode = initiateData.code;
	const verificationUrl = initiateData.verificationUrl;
	const expiresInSeconds = initiateData.expiresIn;
	if (!userCode || !verificationUrl || typeof expiresInSeconds !== "number" || expiresInSeconds <= 0) {
		throw new AIError.OAuthError("Kilo device authorization response missing required fields", {
			kind: "validation",
			provider: "kilo",
		});
	}

	callbacks.onAuth?.({

View on GitHub (pinned to 9690622007)

Solutions

  1. Inspect the error's status field to identify the HTTP cause (5xx = server-side, retry later; 4xx = check endpoint/auth).
  2. Check Kilo's service status — 5xx responses usually mean a temporary outage.
  3. Verify network/proxy settings (HTTPS_PROXY, corporate firewall) allow access to the device-auth endpoint.
  4. Update the library — the base URL or API contract may have changed upstream.

Example fix

// before
await loginKilo(callbacks); // throws on 500 with bare message
// after
try {
  await loginKilo(callbacks);
} catch (err) {
  if (AIError.OAuthError.is(err) && err.status >= 500) {
    await Bun.sleep(30_000);
    await loginKilo(callbacks); // retry on server errors
  } else throw err;
}
Defensive patterns

Strategy: try-catch

Validate before calling

// probe the endpoint before running the full flow
const probe = await fetch(KILO_DEVICE_AUTH_BASE_URL, { method: "HEAD" }).catch(() => null);
if (!probe || probe.status >= 500) throw new Error("Kilo device-auth endpoint unavailable; retry later");

Try / catch

try {
  await loginKilo(callbacks);
} catch (err) {
  if (err instanceof AIError.OAuthError && err.message.startsWith("Failed to initiate")) {
    const status = (err as { status?: number }).status;
    if (status && status >= 500) return retryWithBackoff(() => loginKilo(callbacks));
    // 4xx: surface to user, don't blindly retry
  }
  throw err;
}

Prevention

When it happens

Trigger: The POST to KILO_DEVICE_AUTH_BASE_URL to create a device code returns a non-ok, non-429 response — e.g. 500 server error, 502/503 from a proxy, 401/403 due to blocked endpoint, or a 404 because the endpoint path changed.

Common situations: Kilo service outage or maintenance; corporate proxy/firewall intercepting the request; DNS or base-URL misconfiguration pointing at the wrong host; API version change on the provider side.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/d37196dda1055377. Report an issue: GitHub.