{"record":{"id":"d37196dda1055377","repo":"can1357/oh-my-pi","slug":"failed-to-initiate-device-authorization-initiat","errorCode":null,"errorMessage":"Failed to initiate device authorization: ${initiateResponse.status}","messagePattern":"Failed to initiate device authorization: (.+?)","errorType":"exception","errorClass":"AIError.OAuthError","httpStatus":null,"severity":"error","filePath":"packages/ai/src/registry/kilo.ts","lineNumber":35,"sourceCode":"\ttoken?: string;\n}\n\nexport async function loginKilo(callbacks: OAuthController): Promise<OAuthCredentials> {\n\tconst fetchImpl = callbacks.fetch ?? fetch;\n\tconst initiateResponse = await fetchImpl(`${KILO_DEVICE_AUTH_BASE_URL}/codes`, {\n\t\tmethod: \"POST\",\n\t\theaders: { \"Content-Type\": \"application/json\" },\n\t});\n\n\tif (!initiateResponse.ok) {\n\t\tif (initiateResponse.status === 429) {\n\t\t\tthrow new AIError.OAuthError(\"Too many pending authorization requests. Please try again later.\", {\n\t\t\t\tkind: \"polling\",\n\t\t\t\tprovider: \"kilo\",\n\t\t\t\tstatus: initiateResponse.status,\n\t\t\t});\n\t\t}\n\t\tthrow new AIError.OAuthError(`Failed to initiate device authorization: ${initiateResponse.status}`, {\n\t\t\tkind: \"device-auth\",\n\t\t\tprovider: \"kilo\",\n\t\t\tstatus: initiateResponse.status,\n\t\t});\n\t}\n\n\tconst initiateData = (await initiateResponse.json()) as KiloDeviceAuthCodeResponse;\n\tconst userCode = initiateData.code;\n\tconst verificationUrl = initiateData.verificationUrl;\n\tconst expiresInSeconds = initiateData.expiresIn;\n\tif (!userCode || !verificationUrl || typeof expiresInSeconds !== \"number\" || expiresInSeconds <= 0) {\n\t\tthrow new AIError.OAuthError(\"Kilo device authorization response missing required fields\", {\n\t\t\tkind: \"validation\",\n\t\t\tprovider: \"kilo\",\n\t\t});\n\t}\n\n\tcallbacks.onAuth?.({","sourceCodeStart":17,"sourceCodeEnd":53,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/ai/src/registry/kilo.ts#L17-L53","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Inspect the error's status field to identify the HTTP cause (5xx = server-side, retry later; 4xx = check endpoint/auth).","Check Kilo's service status — 5xx responses usually mean a temporary outage.","Verify network/proxy settings (HTTPS_PROXY, corporate firewall) allow access to the device-auth endpoint.","Update the library — the base URL or API contract may have changed upstream."],"exampleFix":"// before\nawait loginKilo(callbacks); // throws on 500 with bare message\n// after\ntry {\n  await loginKilo(callbacks);\n} catch (err) {\n  if (AIError.OAuthError.is(err) && err.status >= 500) {\n    await Bun.sleep(30_000);\n    await loginKilo(callbacks); // retry on server errors\n  } else throw err;\n}","handlingStrategy":"try-catch","validationCode":"// probe the endpoint before running the full flow\nconst probe = await fetch(KILO_DEVICE_AUTH_BASE_URL, { method: \"HEAD\" }).catch(() => null);\nif (!probe || probe.status >= 500) throw new Error(\"Kilo device-auth endpoint unavailable; retry later\");","typeGuard":null,"tryCatchPattern":"try {\n  await loginKilo(callbacks);\n} catch (err) {\n  if (err instanceof AIError.OAuthError && err.message.startsWith(\"Failed to initiate\")) {\n    const status = (err as { status?: number }).status;\n    if (status && status >= 500) return retryWithBackoff(() => loginKilo(callbacks));\n    // 4xx: surface to user, don't blindly retry\n  }\n  throw err;\n}","preventionTips":["Read the error's status field before choosing to retry (5xx retry, 4xx fix config).","Check proxy env vars (HTTPS_PROXY) allow the device-auth host.","Keep the client library updated for endpoint/base-URL changes.","Monitor provider status pages during outages."],"tags":["oauth","kilo","device-flow","http-error","network"],"backgroundTag":"device-authorization-failed","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}