decolua/9router · error · Error
Failed to export database
Error message
Failed to export database
What it means
ProfilePage's database export handler throws this when GET /api/settings/database (sent with an x-9r-password header) responds non-2xx without a specific error field. Export requires a correct admin password; the generic message commonly masks a wrong-password 401 or a server-side dump failure.
Source
Thrown at src/app/(dashboard)/dashboard/profile/page.js:666
const res = await fetch("/api/settings");
if (!res.ok) return;
const data = await res.json();
setSettings(data);
} catch (err) {
console.error("Failed to reload settings:", err);
}
};
const handleExportDatabase = async (password) => {
setDbLoading(true);
setDbStatus({ type: "", message: "" });
try {
const res = await fetch("/api/settings/database", {
headers: { "x-9r-password": password },
});
if (!res.ok) {
const data = await res.json().catch(() => ({}));
throw new Error(data.error || "Failed to export database");
}
const payload = await res.json();
const content = JSON.stringify(payload, null, 2);
const blob = new Blob([content], { type: "application/json" });
const url = URL.createObjectURL(blob);
const anchor = document.createElement("a");
const stamp = new Date().toISOString().replace(/[.:]/g, "-");
anchor.href = url;
anchor.download = `9router-backup-${stamp}.json`;
document.body.appendChild(anchor);
anchor.click();
document.body.removeChild(anchor);
URL.revokeObjectURL(url);
setDbStatus({ type: "success", message: "Database backup downloaded" });
} catch (err) {
setDbStatus({ type: "error", message: err.message || "Failed to export database" });View on GitHub (pinned to 90b52e06ff)
Solutions
- Check the HTTP status/network response of the export request for the real error
- Re-enter the admin password correctly (most common cause is a wrong x-9r-password)
- Retry after confirming the server is running and the database file is readable
- Check server logs for a serialization/dump failure if the password is confirmed correct
Example fix
// before
throw new Error(data.error || "Failed to export database");
// after
throw new Error(data.error || `Failed to export database (HTTP ${res.status})`); Defensive patterns
Strategy: try-catch
Validate before calling
// before calling
if (!password) throw new Error("Admin password required to export"); Try / catch
try {
const res = await fetch("/api/settings/database", { headers: { "x-9r-password": password } });
if (!res.ok) {
const data = await res.json().catch(() => ({}));
throw new Error(data.error || `Failed to export database (HTTP ${res.status})`);
}
} catch (err) {
setDbStatus({ type: "error", message: err.message });
} Prevention
- Re-enter the admin password carefully on 401/403
- Handle 401 distinctly to prompt re-authentication instead of a generic failure
- For large DBs, expect longer export times and retry on timeout
- Verify the server version supports the export endpoint
When it happens
Trigger: GET /api/settings/database with header x-9r-password returns non-2xx: password incorrect/missing (401/403), server fails to serialize the SQLite data (500), or res.json() succeeds but data.error is absent.
Common situations: User typed the dashboard admin password wrong in the export prompt; database is large and dump times out; running an older server version whose endpoint requires different auth; empty password field submitted.
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
- qoder PAT exchange failed: ${res.status} ${text.slice(0, 200
- GitHub API error: ${error}
- Failed to import database
- Missing API key
- Invalid API key
AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30).
Data as JSON: /api/errors/5dfd91f820ad5fcd.
Report an issue: GitHub.