srbhr/Resume-Matcher · error · Error
${data.detail || Failed to reset database (status ${res.stat
Error message
${data.detail || Failed to reset database (status ${res.status}).} What it means
resetDatabase POSTs to /config/reset with body {confirm: 'RESET_ALL_DATA'} and throws this when the response is not ok, preferring the backend `detail`. It wipes all resumes/jobs/config data; the backend requires the exact confirm token, and any non-2xx (refusal, auth, crash) is reported through this throw to handleResetDatabase.
Source
Thrown at apps/frontend/lib/api/config.ts:543
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> {
const res = await apiFetch('/config/reset', {
method: 'POST',
credentials: 'include',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ confirm: 'RESET_ALL_DATA' }),
});
if (!res.ok) {
const data = await res.json().catch(() => ({}));
throw new Error(data.detail || `Failed to reset database (status ${res.status}).`);
}
}
View on GitHub (pinned to 116f9cc3b0)
Solutions
- Ensure the request body is exactly {confirm: 'RESET_ALL_DATA'} with Content-Type: application/json.
- 401/403 → re-authenticate and retry; 404 → check BACKEND_ORIGIN and next.config.ts rewrites.
- For 5xx, inspect backend logs — a partial reset may need the DB/volume permission or lock issue fixed before retrying.
- Gate the action behind a typed confirmation dialog and catch the error to report reset failure clearly instead of leaving stale UI.
Example fix
// before
try {
await resetDatabase();
} finally {
window.location.reload();
}
// after
try {
await resetDatabase();
window.location.reload();
} catch (e) {
setResetError(e instanceof Error ? e.message : 'Database reset failed — data was NOT cleared');
} Defensive patterns
Strategy: validation
Validate before calling
const body = JSON.stringify({ confirm: 'RESET_ALL_DATA' });
if (!body.includes('RESET_ALL_DATA')) {
throw new Error('Reset requires the RESET_ALL_DATA confirm token');
} Type guard
function isResetBody(x: unknown): x is { confirm: 'RESET_ALL_DATA' } {
return typeof x === 'object' && x !== null && (x as any).confirm === 'RESET_ALL_DATA';
} Try / catch
const phrase = await confirmDialog({
title: 'Reset database? All resumes and jobs will be deleted.',
requireTyped: 'RESET',
});
if (!phrase) return;
try {
await resetDatabase();
showToast('Database reset');
} catch (e) {
setResetError(e instanceof Error ? e.message : 'Reset failed — data intact');
} Prevention
- Always send Content-Type: application/json with the confirm body
- Use a typed-confirmation dialog for irreversible resets
- Never reload the page in a finally block — wait for success
- Check DB file locks and volume permissions if the reset 500s repeatedly
When it happens
Trigger: Non-2xx on POST /config/reset: 400/403 when the confirm body is absent or doesn't equal 'RESET_ALL_DATA', 401 (expired session), 404 (route/proxy misroute), 500/503 when the backend fails mid-reset (DB locked, file permissions, disk full).
Common situations: Hand-rolled requests omitting the confirm payload; session expiring before the destructive click; SQLite file locked by another process; Docker volume mounted read-only so the DB can't be cleared.
Related errors
- ${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
- Failed to load feature prompts (status ${res.status}).
- ${message = errBody.detail or Failed to update feature promp
AI-assisted analysis of srbhr/Resume-Matcher@116f9cc3b0 (2026-08-28).
Data as JSON: /api/errors/36279b6f87afb66d.
Report an issue: GitHub.