paperclipai/paperclip · error
database_unavailable
Error message
database_unavailable
What it means
This is an HTTP 503 JSON error from POST /dev-server/restart in the health router. The route first confirms a restart is actually required from persisted dev-server supervisor status; only then does it need the database handle to run a preflight query for active heartbeat runs before writing a hot-restart intent. When the `db` handle was never injected into healthRoutes (it is optional), the route cannot safely coordinate the restart and returns `database_unavailable` with status 503.
Source
Thrown at server/src/routes/health.ts:161
}
const persistedDevServerStatus = readPersistedDevServerStatus();
if (!persistedDevServerStatus) {
res.status(404).json({ error: "dev_server_supervisor_unavailable" });
return;
}
const restartRequired =
persistedDevServerStatus.dirty ||
persistedDevServerStatus.changedPathCount > 0 ||
persistedDevServerStatus.pendingMigrations.length > 0;
if (!restartRequired) {
res.status(409).json({ error: "restart_not_required" });
return;
}
if (!db) {
res.status(503).json({ error: "database_unavailable" });
return;
}
const requestId = randomUUID();
const requestedAt = new Date();
const serverInfo = opts.serverInfo ?? getServerInfoSnapshot();
const preflightActiveRunIds = await db
.select({ id: heartbeatRuns.id })
.from(heartbeatRuns)
.where(eq(heartbeatRuns.status, "running"))
.then((rows) => rows.map((row) => row.id));
let intent: Awaited<ReturnType<typeof writeHotRestartIntent>> | null = null;
try {
intent = await writeHotRestartIntent({
previousServerPid: process.pid,
previousServerIdentity: serverInfo.processStartedAt,
previousServerVersion: serverVersion,
preflightActiveRunIds,View on GitHub (pinned to 01ad858492)
Solutions
- Restart the server ensuring the database initializes before health routes are wired (set DATABASE_URL or allow embedded PGlite setup to complete).
- Check startup logs for DB init failure (connection refused, bad DATABASE_URL) and fix the connection first.
- If using embedded dev DB, remove data/pglite and re-run `pnpm dev` for a clean initialization.
- Verify the code path that constructs healthRoutes passes the `db` argument once the DB client exists.
- As a stopgap, perform a cold restart of the dev server instead of the hot-restart endpoint.
Example fix
// before: health routes wired without a db handle when DB is optional
createHealthRouter({ deploymentMode, authReady });
// after: pass the initialized db so preflight can run
if (!db) throw new Error("database unavailable at startup");
createHealthRouter({ deploymentMode, authReady }, db); Defensive patterns
Strategy: retry
Validate before calling
// before calling the restart endpoint
const health = await fetch('/api/health').then(r => r.json());
if (!health.database || health.database.status !== 'ok') {
throw new Error('database not available; hot restart cannot preflight active runs');
} Type guard
function isDbUnavailable(err: { status?: number; error?: string }): boolean {
return err.status === 503 && err.error === 'database_unavailable';
} Try / catch
const res = await api.post('/api/dev-server/restart');
if (res.status === 503 && (await res.json()).error === 'database_unavailable') {
await waitForDbReady({ timeoutMs: 30000 });
return retryRestart();
} Prevention
- Gate the dev-server "Restart now" UI on a healthy /api/health database status.
- Ensure the db client is fully initialized before registering health routes.
- Set and validate DATABASE_URL at startup; fail fast with a clear message.
- In embedded-PGlite dev, avoid deleting data/pglite while the server is running.
When it happens
Trigger: POST /api/dev-server/restart is called when the persisted dev-server status says a restart IS required (dirty, changedPathCount > 0, or pendingMigrations) but the server was constructed without a `db` instance, so the preflight active-run check cannot run.
Common situations: Starting the server in a mode where the DB client is intentionally not wired (embedded PGlite not initialized, DATABASE_URL unset and init failed); clicking "Restart now" in the dev UI while the server booted degraded without a database; partial startup where health routes registered before DB init completed.
Related errors
- Plugin is not ready (current status: ${plugin.status})
- Plugin worker is not running
- Execution workspace needs a local path before Paperclip can
- managed_profile_unavailable
- agentcore_profile_unavailable
AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10).
Data as JSON: /api/errors/25ade9eb5ecd3453.
Report an issue: GitHub.