{"record":{"id":"85f0fa5161e052af","repo":"different-ai/openwork","slug":"failed-to-delete-api-key-response-status","errorCode":null,"errorMessage":"Failed to delete API key (${response.status}).","messagePattern":"Failed to delete API key \\((.+?)\\)\\.","errorType":"http","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"ee/apps/den-web/app/(den)/dashboard/_components/api-keys-screen.tsx","lineNumber":254,"sourceCode":"                `Delete ${apiKey.name ?? apiKey.start ?? \"this API key\"}? This cannot be undone.`,\n            )\n        ) {\n            return;\n        }\n\n        setError(null);\n        try {\n            await runReauthableAction(\"delete-api-key\", async () => {\n                setDeletingId(apiKey.id);\n                try {\n                    const { response, payload } = await requestJson(\n                        `/v1/api-keys/${encodeURIComponent(apiKey.id)}`,\n                        { method: \"DELETE\" },\n                        12000,\n                    );\n\n                    if (response.status !== 204 && !response.ok) {\n                        throw getRequestError(\n                            payload,\n                            response,\n                            `Failed to delete API key (${response.status}).`,\n                        );\n                    }\n\n                    await loadApiKeys();\n                } finally {\n                    setDeletingId(null);\n                }\n            });\n        } catch (nextError) {\n            setError(\n                nextError instanceof Error\n                    ? nextError.message\n                    : \"Failed to delete API key.\",\n            );\n        }","sourceCodeStart":236,"sourceCodeEnd":272,"githubUrl":"https://github.com/different-ai/openwork/blob/2b7df46e8ae1517d64c896c7793d2d52ec845669/ee/apps/den-web/app/(den)/dashboard/_components/api-keys-screen.tsx#L236-L272","documentation":"handleDelete sends DELETE /v1/api-keys/:id and treats success as status 204 or any 2xx; anything else throws getRequestError(payload, response, 'Failed to delete API key (<status>)'). Note the guard explicitly allows 204 even if some clients report it as not-ok. It exists so the UI shows a precise failure instead of silently leaving the key in the list.","triggerScenarios":"DELETE /v1/api-keys/{id} returns non-204 and non-ok: 401/403 (no permission / expired session), 404 (key already deleted or wrong org/id), 409 (key in use), 429, or 5xx.","commonSituations":"Deleting a key that another admin already removed (404 on stale list data); user lacking delete permission; revoked/expired session; double-click issuing two deletes, the second hitting 404; Den backend outage.","solutions":["For 404, refresh the key list — the key is already gone, so treat it as success and update local state.","For 401/403, re-authenticate or use an account with delete permissions.","Disable the delete button while a request is in flight to avoid duplicate deletes.","Retry with backoff on 429/5xx; check Den server logs if persistent."],"exampleFix":"// before\nawait handleDelete(apiKey); // throws on 404 after a concurrent delete\n// after\ntry {\n  await handleDelete(apiKey);\n} catch (e) {\n  if (e.status === 404) { refreshKeys(); /* already deleted */ return; }\n  throw e;\n}","handlingStrategy":"try-catch","validationCode":"if (!apiKey?.id) throw new Error(\"Refusing to delete: API key has no id\");\nif (!keys.some(k => k.id === apiKey.id)) throw new Error(\"Key no longer in list; refresh before deleting\");","typeGuard":"function isDeletableKey(k, currentKeys) {\n  return Boolean(k && typeof k.id === \"string\" && k.id.length > 0 && currentKeys.some(x => x.id === k.id));\n}","tryCatchPattern":"try {\n  await handleDelete(apiKey);\n} catch (e) {\n  const status = e.status ?? Number(/\\((\\d{3})\\)/.exec(e.message)?.[1]);\n  if (status === 404) refreshKeys(); // already deleted elsewhere\n  else if (status === 401 || status === 403) redirectToSignIn();\n  else setError(\"Delete failed; the key remains. Try again.\");\n}","preventionTips":["Refresh the key list before delete operations to avoid 404s on stale data.","Disable the delete control while a request is in flight to prevent double deletes.","Treat 404 as success-and-refresh for idempotent deletes.","Re-authenticate on 401 and surface 403 as a permission problem."],"tags":["den","api","http","api-key","delete"],"backgroundTag":"http-request-failed","analyzedSha":"2b7df46e8ae1517d64c896c7793d2d52ec845669","analyzedAt":"2026-09-01T07:59:23.713Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}