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

  1. Check the HTTP status/network response of the export request for the real error
  2. Re-enter the admin password correctly (most common cause is a wrong x-9r-password)
  3. Retry after confirming the server is running and the database file is readable
  4. 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

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


AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30). Data as JSON: /api/errors/5dfd91f820ad5fcd. Report an issue: GitHub.