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

  1. Ensure the request body is exactly {confirm: 'RESET_ALL_DATA'} with Content-Type: application/json.
  2. 401/403 → re-authenticate and retry; 404 → check BACKEND_ORIGIN and next.config.ts rewrites.
  3. For 5xx, inspect backend logs — a partial reset may need the DB/volume permission or lock issue fixed before retrying.
  4. 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

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


AI-assisted analysis of srbhr/Resume-Matcher@116f9cc3b0 (2026-08-28). Data as JSON: /api/errors/36279b6f87afb66d. Report an issue: GitHub.