{"record":{"id":"b0e5937619ad2be2","repo":"JuliusBrussee/caveman","slug":"caveman-remote-gateway-key-revocation-failed-htt","errorCode":null,"errorMessage":"caveman: remote gateway key revocation failed (HTTP ${response.status}); credentials kept — retry `caveman logout`","messagePattern":"caveman: remote gateway key revocation failed \\(HTTP (.+?)\\); credentials kept — retry `caveman logout`","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/cli/src/index.ts","lineNumber":9452,"sourceCode":"\tconst cfg = await config();\n\tconst externalToken = Boolean(process.env.CAVE_TOKEN);\n\tif (cfg.token && (!cfg.logoutPendingLocalCleanup || externalToken)) {\n\t  if (cfg.projectId && cfg.gatewayKeyId) {\n\t    let response: Response;\n\t    try {\n\t      response = await fetch(`${cfg.baseURL}/api/v1/projects/${encodeURIComponent(cfg.projectId)}/keys/${encodeURIComponent(cfg.gatewayKeyId)}/revoke`, {\n\t        method: \"POST\",\n\t        headers: { authorization: `Bearer ${cfg.token}`, \"content-type\": \"application/json\", \"x-cave-csrf\": \"cli\" },\n\t        body: \"{}\",\n\t        signal: AbortSignal.timeout(5000),\n\t      });\n\t    } catch {\n\t      throw new Error(\"caveman: remote gateway key revocation was unavailable; credentials kept — retry `caveman logout`\");\n\t    }\n\t    if (!response.ok) {\n\t      const body = await response.json().catch(() => null) as { error?: { code?: unknown } } | null;\n\t      const alreadyRevoked = response.status === 404 && body?.error?.code === \"cave_key_not_found\";\n\t      if (!alreadyRevoked) throw new Error(`caveman: remote gateway key revocation failed (HTTP ${response.status}); credentials kept — retry \\`caveman logout\\``);\n\t    }\n\t  }\n\t  const headers: Record<string, string> = {\n\t    authorization: `Bearer ${cfg.token}`,\n\t    \"x-cave-client\": \"cli\",\n\t  };\n\t  const request: RequestInit = {\n\t    method: \"POST\",\n\t    headers,\n\t    signal: AbortSignal.timeout(5000),\n\t  };\n\t  if (cfg.refreshToken) {\n\t    headers[\"content-type\"] = \"application/json\";\n\t    request.body = JSON.stringify({ refresh_token: cfg.refreshToken });\n\t  }\n\t  let response: Response;\n\t  try {\n\t    response = await fetch(`${cfg.baseURL}/api/v1/auth/logout`, request);","sourceCodeStart":9434,"sourceCodeEnd":9470,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/5184b3d11ac6a1acb7d44b9bfaa31698157cff97/packages/cli/src/index.ts#L9434-L9470","documentation":"During `caveman logout`, the request to revoke the gateway key on the server returned a non-2xx status. Local credentials are deliberately kept (not deleted) so the user can retry; a failed revocation with deleted credentials would leave a live key on the server.","triggerScenarios":"Thrown at packages/cli/src/index.ts:8607 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Retry `caveman logout`; check the HTTP status in the message (5xx → server issue)","If retries fail, revoke the key via the cloud dashboard"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"5184b3d11ac6a1acb7d44b9bfaa31698157cff97","analyzedAt":"2026-08-18T03:14:35.516Z","contentChangedAt":"2026-08-18T03:14:35.516Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}