srbhr/Resume-Matcher · error · Error
${data.detail || Failed to delete API key (status ${res.stat
Error message
${data.detail || Failed to delete API key (status ${res.status}).} What it means
deleteApiKey issues DELETE for one provider's key on /config/api-keys and throws this when the response is not ok, preferring the backend `detail` string and falling back to the status-code message. It has no return value, so the throw is the only failure signal to handleDeleteApiKey.
Source
Thrown at apps/frontend/lib/api/config.ts:515
if (!res.ok) {
const data = await res.json().catch(() => ({}));
throw new Error(data.detail || `Failed to update API keys (status ${res.status}).`);
}
return res.json();
}
// Delete API key for a specific provider
export async function deleteApiKey(provider: ApiKeyProvider): Promise<void> {
const res = await apiFetch(`/config/api-keys/${provider}`, {
method: 'DELETE',
credentials: 'include',
});
if (!res.ok) {
const data = await res.json().catch(() => ({}));
throw new Error(data.detail || `Failed to delete API key (status ${res.status}).`);
}
}
// Clear all API keys
export async function clearAllApiKeys(): Promise<void> {
const res = await apiFetch('/config/api-keys?confirm=CLEAR_ALL_KEYS', {
method: 'DELETE',
credentials: 'include',
});
if (!res.ok) {
const data = await res.json().catch(() => ({}));
throw new Error(data.detail || `Failed to clear API keys (status ${res.status}).`);
}
}
// Reset database
export async function resetDatabase(): Promise<void> {View on GitHub (pinned to 116f9cc3b0)
Solutions
- 404 → treat as 'already deleted' or verify the provider id matches PROVIDER_INFO and the deployed backend's enum.
- 401/403 → re-authenticate and retry; 5xx → check backend logs for key-store errors.
- Catch in handleDeleteApiKey, show the detail message, then refresh the key-status list so the UI matches server state.
- Avoid double-clicking delete: disable the button while the request is in flight to prevent duplicate 404s.
Example fix
// before
await deleteApiKey(provider);
refreshKeys();
// after
try {
await deleteApiKey(provider);
} catch (e) {
showToast(e instanceof Error ? e.message : 'Delete failed');
} finally {
refreshKeys();
} Defensive patterns
Strategy: try-catch
Validate before calling
if (!SUPPORTED.includes(provider)) {
throw new Error(`Unknown provider: ${provider}`);
} Type guard
function is deletableProvider(p: string): boolean {
return SUPPORTED.includes(p);
} Try / catch
try {
await deleteApiKey(provider);
} catch (e) {
const msg = e instanceof Error ? e.message : '';
if (msg.includes('status 404')) {
showToast('Key was already removed');
} else {
showToast(msg || 'Delete failed');
}
} finally {
refreshKeys();
} Prevention
- Refresh key status after every delete to keep UI in sync
- Disable the delete button while a delete is in flight
- Verify provider ids against the deployed backend enum
- Re-authenticate instead of retrying deletes after 401
When it happens
Trigger: Non-2xx on DELETE /config/api-keys/<provider>: 401/403 (expired session/CSRF), 404 (the provider has no stored key, or the route/provider id is unknown — mismatched frontend/backend provider enums), 422 (malformed provider identifier), 500 (key-store deletion failed).
Common situations: Deleting a key that was already removed in another tab (404); session expired between page load and the delete click; backend upgrade renamed a provider slug; DB lock preventing the delete.
Related errors
- Failed to load API key status (status ${res.status}).
- ${data.detail || Failed to update API keys (status ${res.sta
- ${data.detail || Failed to clear API keys (status ${res.stat
- Failed to load prompt config (status ${res.status}).
- ${data.detail || Failed to update prompt config (status ${re
AI-assisted analysis of srbhr/Resume-Matcher@116f9cc3b0 (2026-08-28).
Data as JSON: /api/errors/2347a4c1252098f3.
Report an issue: GitHub.