thedotmack/claude-mem · error
CLAUDE_MEM_SERVER_DATABASE_URL is required for `server ${com
Error message
CLAUDE_MEM_SERVER_DATABASE_URL is required for `server ${commandLabel}`. This command talks to the server Postgres backend; export the connection string before running it. What it means
Thrown by assertServerRuntimeForCli() when CLAUDE_MEM_SERVER_DATABASE_URL is empty/unset and a `server <command>` operation is invoked. Server CLI commands talk to the Postgres backend, so the connection string is mandatory. This is a fast-fail so the command doesn't proceed to an opaque pool/connection error.
Source
Thrown at src/server/runtime/ServerService.ts:460
// or no `CLAUDE_MEM_SERVER_DATABASE_URL` configured — we fail fast with an
// actionable message instead of crashing later with an opaque pool error.
//
// Phase 1d: dual-accept the persisted runtime literal (`'server'` is the new
// canonical form; `'server-beta'` remains valid for existing installs).
export function assertServerRuntimeForCli(
commandLabel: string,
env: NodeJS.ProcessEnv = process.env,
): void {
const runtime = (env.CLAUDE_MEM_RUNTIME ?? '').trim().toLowerCase();
if (runtime && runtime !== 'server' && runtime !== 'server-beta') {
throw new Error(
`\`server ${commandLabel}\` is a server runtime command, but CLAUDE_MEM_RUNTIME=${runtime}. ` +
'Set CLAUDE_MEM_RUNTIME=server (and CLAUDE_MEM_SERVER_DATABASE_URL) to run server operations, ' +
'or use the worker CLI (`worker-service ...`) for the worker runtime.',
);
}
if (!(env.CLAUDE_MEM_SERVER_DATABASE_URL ?? '').trim()) {
throw new Error(
`CLAUDE_MEM_SERVER_DATABASE_URL is required for \`server ${commandLabel}\`. ` +
'This command talks to the server Postgres backend; export the connection string before running it.',
);
}
}
export async function runServerApiKeyCli(argv: string[]): Promise<void> {
const sub = argv[0]?.toLowerCase();
const options = parseFlagArgs(argv.slice(1));
try {
assertServerRuntimeForCli('api-key');
} catch (error) {
console.error(error instanceof Error ? error.message : String(error));
process.exit(1);
}
// #2560 — `api-key migrate-scopes <id>` brings a key's scope set up to aView on GitHub (pinned to d768ba3643)
Solutions
- Export CLAUDE_MEM_SERVER_DATABASE_URL to a valid Postgres connection string (postgres://user:pass@host:5432/db) before running the command.
- Ensure the variable is set in the same shell/session that runs the CLI (or in the container env / systemd unit / .env loaded by the launcher).
- Confirm the database is reachable and the user has the required privileges.
- Set CLAUDE_MEM_RUNTIME=server alongside it if not already set.
Example fix
// before: CLAUDE_MEM_SERVER_DATABASE_URL unset // after: export CLAUDE_MEM_SERVER_DATABASE_URL=postgres://app:secret@db:5432/claude_mem // claude-mem server api-key create
Defensive patterns
Strategy: validation
Validate before calling
function assertServerDatabaseUrl(env: NodeJS.ProcessEnv = process.env): void {
if (!(env.CLAUDE_MEM_SERVER_DATABASE_URL ?? '').trim()) {
throw new Error('Export CLAUDE_MEM_SERVER_DATABASE_URL (postgres://...) before running server commands');
}
} Type guard
function hasServerDatabaseUrl(env: NodeJS.ProcessEnv): boolean {
return Boolean((env.CLAUDE_MEM_SERVER_DATABASE_URL ?? '').trim());
} Try / catch
try {
assertServerRuntimeForCli('api-key');
} catch (error) {
if (/CLAUDE_MEM_SERVER_DATABASE_URL is required/.test((error as Error).message)) {
console.error('Export CLAUDE_MEM_SERVER_DATABASE_URL before retrying.');
process.exit(1);
}
throw error;
} Prevention
- Always export CLAUDE_MEM_SERVER_DATABASE_URL in any shell/container running server commands.
- Put the variable in the launcher (systemd unit, Docker env, .env loaded by the app).
- Confirm the Postgres user has the required privileges before first run.
When it happens
Trigger: Running `claude-mem server <commandLabel>` (e.g. api-key, or any server-runtime operation) without CLAUDE_MEM_SERVER_DATABASE_URL exported; the variable is set but whitespace-only (it is trimmed before the check).
Common situations: Fresh server install where the operator hasn't configured the database yet. The variable was exported in a different shell/session. A typo in the variable name.
Related errors
- Postgres requires CLAUDE_MEM_SERVER_DATABASE_URL
- `server ${commandLabel}` is a server runtime command, but CL
- Postgres requires CLAUDE_MEM_SERVER_DATABASE_URL
- Unknown Claude model: ${options.model}. Allowed: ${[...allow
- Invalid CLAUDE_MEM_QUEUE_ENGINE=${raw}; expected sqlite or b
AI-assisted analysis of thedotmack/claude-mem@d768ba3643 (2026-08-12).
Data as JSON: /api/errors/79c4b89a3ecc1870.
Report an issue: GitHub.