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

  1. For 404, refresh the key list — the key is already gone, so treat it as success and update local state.
  2. For 401/403, re-authenticate or use an account with delete permissions.
  3. Disable the delete button while a request is in flight to avoid duplicate deletes.
  4. 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

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


AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01). Data as JSON: /api/errors/85f0fa5161e052af. Report an issue: GitHub.