{"record":{"id":"f63ad7f930561ebd","repo":"JuliusBrussee/caveman","slug":"device-credential-delivery-acknowledgement-failed","errorCode":null,"errorMessage":"device credential delivery acknowledgement failed (${lastError}); credentials were persisted locally but the server may revoke them after the delivery window","messagePattern":"device credential delivery acknowledgement failed \\((.+?)\\); credentials were persisted locally but the server may revoke them after the delivery window","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/cli/src/index.ts","lineNumber":9659,"sourceCode":"          \"content-type\": \"application/json\",\n          \"x-cave-client\": \"cli\",\n        },\n        body: JSON.stringify({ device_code: deviceCode, ack_token: ackToken }),\n        signal: AbortSignal.timeout(5000),\n      });\n      if (response.ok) return;\n      const body = await response.json().catch(() => null) as { error?: { code?: unknown } } | null;\n      const code = typeof body?.error?.code === \"string\" ? body.error.code : `HTTP ${response.status}`;\n      lastError = code;\n      // Invalid/expired grants are terminal. Infrastructure responses remain\n      // retryable so a committed ACK whose response was dropped can converge.\n      if (response.status < 500 && response.status !== 429) break;\n    } catch (error) {\n      lastError = error instanceof Error ? error.message : String(error);\n    }\n    if (attempt < 4) await sleep(Math.min(2000, 200 * 2 ** attempt));\n  }\n  throw new Error(`device credential delivery acknowledgement failed (${lastError}); credentials were persisted locally but the server may revoke them after the delivery window`);\n}\n\n// 0600 credentials file) — never in plaintext config. organization_id is bound\n// from the returned token, never from any local input.\n// Hosted login remains gated; explicit private instances use project access.\nfunction blockCloudLoginWhileBeta(): void {\n  throw new Error(\"Caveman Cloud platform is still in beta.\");\n}\n\nasync function login(argv: string[] = []) {\n  if (!argv.some((arg) => arg === \"--instance\" || arg.startsWith(\"--instance=\"))) blockCloudLoginWhileBeta();\n  const { noBrowser, instance } = validateLoginArgs(argv);\n  const baseURL = instance ?? resolveLoginBaseUrl(argv);\n\n  const codeResp = await fetch(`${baseURL}/api/v1/auth/device/code`, {\n    method: \"POST\",\n    redirect: \"error\",\n    headers: { \"content-type\": \"application/json\" },","sourceCodeStart":9641,"sourceCodeEnd":9677,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/3ee70a102609e550bd2e68004bf5990a9341c851/packages/cli/src/index.ts#L9641-L9677","documentation":"After a successful private device login the CLI must acknowledge to the control plane that it stored the credential bundle, using a delivery_ack_token. This acknowledgement POST is retried up to 5 times (only retrying on 5xx/429 and network errors); if the last attempt still fails, this error is thrown. Credentials are already saved locally, but the server may revoke them once the delivery window expires.","triggerScenarios":"acknowledgeDeviceGrant exhausts all 5 attempts because the instance's acknowledgement endpoint keeps returning network errors/exceptions or 5xx/429 statuses, or returns a non-retryable error on the final attempt.","commonSituations":"Private instance briefly down or deploying during login; corporate proxy intercepting the acknowledgement POST; rate limiting (429) persisting past the retry window; DNS or TLS problems reaching the instance.","solutions":["Retry `login` once the instance is reachable — credentials are already stored locally","Check instance health/logs for errors on the delivery-acknowledgement endpoint","Verify network/proxy allows POSTs to the instance's acknowledgement URL","Re-run device login to obtain a fresh grant before the delivery window revokes the credentials"],"exampleFix":"// before\nawait acknowledgeDeviceGrant(baseURL, credentials.access_token, code.device_code, ackToken);\n// after\ntry {\n  await acknowledgeDeviceGrant(baseURL, credentials.access_token, code.device_code, ackToken);\n} catch (e) {\n  console.warn(\"ack failed, re-login to refresh the grant:\", e.message);\n}","handlingStrategy":"retry","validationCode":"const reachable = await fetch(baseURL + \"/healthz\", { signal: AbortSignal.timeout(3000) }).then(r => r.ok).catch(() => false);\nif (!reachable) console.warn(\"Instance unreachable; acknowledgement will likely fail\");","typeGuard":null,"tryCatchPattern":"try { await login({ instance }) } catch (e) { if (e.message.includes(\"acknowledgement failed\")) scheduleRetryLogin(); }","preventionTips":["Ensure the instance is healthy before initiating login","Avoid running login during instance deploys or network maintenance","Whitelist the acknowledgement endpoint in proxies/firewalls"],"tags":["network","oauth","retry-exhausted","device-flow"],"backgroundTag":"api-request-failed","analyzedSha":"3ee70a102609e550bd2e68004bf5990a9341c851","analyzedAt":"2026-09-20T15:53:39.229Z","contentChangedAt":"2026-09-20T15:53:39.229Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}