different-ai/openwork · error · Error
Failed to delete API key (${response.status}).
Error message
Failed to delete API key (${response.status}). What it means
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.
Source
Thrown at ee/apps/den-web/app/(den)/dashboard/_components/api-keys-screen.tsx:254
`Delete ${apiKey.name ?? apiKey.start ?? "this API key"}? This cannot be undone.`,
)
) {
return;
}
setError(null);
try {
await runReauthableAction("delete-api-key", async () => {
setDeletingId(apiKey.id);
try {
const { response, payload } = await requestJson(
`/v1/api-keys/${encodeURIComponent(apiKey.id)}`,
{ method: "DELETE" },
12000,
);
if (response.status !== 204 && !response.ok) {
throw getRequestError(
payload,
response,
`Failed to delete API key (${response.status}).`,
);
}
await loadApiKeys();
} finally {
setDeletingId(null);
}
});
} catch (nextError) {
setError(
nextError instanceof Error
? nextError.message
: "Failed to delete API key.",
);
}View on GitHub (pinned to 2b7df46e8a)
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.
Example fix
// before
await handleDelete(apiKey); // throws on 404 after a concurrent delete
// after
try {
await handleDelete(apiKey);
} catch (e) {
if (e.status === 404) { refreshKeys(); /* already deleted */ return; }
throw e;
} Defensive patterns
Strategy: try-catch
Validate before calling
if (!apiKey?.id) throw new Error("Refusing to delete: API key has no id");
if (!keys.some(k => k.id === apiKey.id)) throw new Error("Key no longer in list; refresh before deleting"); Type guard
function isDeletableKey(k, currentKeys) {
return Boolean(k && typeof k.id === "string" && k.id.length > 0 && currentKeys.some(x => x.id === k.id));
} Try / catch
try {
await handleDelete(apiKey);
} catch (e) {
const status = e.status ?? Number(/\((\d{3})\)/.exec(e.message)?.[1]);
if (status === 404) refreshKeys(); // already deleted elsewhere
else if (status === 401 || status === 403) redirectToSignIn();
else setError("Delete failed; the key remains. Try again.");
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
Related errors
- Failed to create API key (${response.status}).
- Failed to load API keys (${response.status}).
- Failed to delete the dashboard (${response.status}).
- Failed to delete skill (${response.status}).
- request_failed
AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01).
Data as JSON: /api/errors/85f0fa5161e052af.
Report an issue: GitHub.