thedotmack/claude-mem · error · Error
Postgres requires CLAUDE_MEM_SERVER_DATABASE_URL
Error message
Postgres requires CLAUDE_MEM_SERVER_DATABASE_URL
What it means
parsePostgresConfig validates that a Postgres connection string exists before constructing a PostgresConfig. When options.requireDatabaseUrl is true and neither CLAUDE_MEM_SERVER_DATABASE_URL nor related env vars yield a connection string, the library throws instead of silently returning null. This is a fail-fast guard for deployments explicitly configured to require Postgres.
Solutions
- Set CLAUDE_MEM_SERVER_DATABASE_URL to a valid postgres:// connection string in the environment before starting the server
- If Postgres is optional, call parsePostgresConfig without requireDatabaseUrl and handle the null return (fall back to SQLite)
- Check that your .env / secret mount / process manager actually passes the variable to the process (print process.env.CLAUDE_MEM_SERVER_DATABASE_URL at startup)
- Verify the variable name spelling and that it is not overwritten by an empty value in shell profiles or docker compose
Example fix
// before
const config = parsePostgresConfig({ env: process.env, requireDatabaseUrl: true });
// after
process.env.CLAUDE_MEM_SERVER_DATABASE_URL ??= 'postgres://user:pass@localhost:5432/claude_mem';
const config = parsePostgresConfig({ env: process.env, requireDatabaseUrl: true }); Defensive patterns
Strategy: validation
Validate before calling
const url = process.env.CLAUDE_MEM_SERVER_DATABASE_URL;
if (!url || !url.startsWith('postgres')) throw new Error('CLAUDE_MEM_SERVER_DATABASE_URL must be set to a postgres:// URL before enabling Postgres'); Type guard
function hasPostgresUrl(env: NodeJS.ProcessEnv): env is NodeJS.ProcessEnv & { CLAUDE_MEM_SERVER_DATABASE_URL: string } {
return typeof env.CLAUDE_MEM_SERVER_DATABASE_URL === 'string' && env.CLAUDE_MEM_SERVER_DATABASE_URL.length > 0;
} Try / catch
try {
config = parsePostgresConfig({ requireDatabaseUrl: true });
} catch (err) {
if (err instanceof Error && err.message.includes('CLAUDE_MEM_SERVER_DATABASE_URL')) {
console.error('Missing CLAUDE_MEM_SERVER_DATABASE_URL; check your environment/.env');
process.exit(1);
}
throw err;
} Prevention
- Always set CLAUDE_MEM_SERVER_DATABASE_URL in deployment manifests when the Postgres backend is enabled
- Load .env files before config parsing runs
- Log which env vars are present (names only) at startup to catch missing config early
- Keep variable names in a single constants file to avoid typos
When it happens
Trigger: Calling parsePostgresConfig({ requireDatabaseUrl: true }) (or via config loading paths that set it) when CLAUDE_MEM_SERVER_DATABASE_URL is unset or empty in process.env or the passed options.env.
Common situations: Deploying the server with a Postgres backend flag enabled but forgetting to export the env var; .env file not loaded; variable named wrong (e.g. DATABASE_URL instead of CLAUDE_MEM_SERVER_DATABASE_URL); running in a container where secrets were not mounted.
Understand the failure class
Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.
Related errors
- CLAUDE_MEM_SERVER_DATABASE_URL is required for `server
- Cannot bootstrap server API key…
- CLAUDE_MEM_HOST_OBSERVER_PORT=
- Invalid , using default
- missing_api_key
AI-assisted analysis of thedotmack/claude-mem@d8bc9755e7 (2026-09-17).
Data as JSON: /api/errors/14aa82466c9f2e36.
Report an issue: GitHub.
Appendix: source
Thrown at src/storage/postgres/config.ts:32
env?: NodeJS.ProcessEnv;
requireDatabaseUrl?: boolean;
}
const DEFAULT_POOL_MAX = 10;
const DEFAULT_IDLE_TIMEOUT_MS = 30_000;
const DEFAULT_CONNECTION_TIMEOUT_MS = 5_000;
const DEFAULT_STATEMENT_TIMEOUT_MS = 30_000;
export function getPostgresDatabaseUrl(env: NodeJS.ProcessEnv = process.env): string | null {
return env.CLAUDE_MEM_SERVER_DATABASE_URL || null;
}
export function parsePostgresConfig(options: ParsePostgresConfigOptions = {}): PostgresConfig | null {
const env = options.env ?? process.env;
const connectionString = getPostgresDatabaseUrl(env);
if (!connectionString) {
if (options.requireDatabaseUrl) {
throw new Error('Postgres requires CLAUDE_MEM_SERVER_DATABASE_URL');
}
return null;
}
return {
connectionString,
max: parsePositiveInt(env.CLAUDE_MEM_POSTGRES_POOL_MAX, DEFAULT_POOL_MAX),
idleTimeoutMillis: parsePositiveInt(env.CLAUDE_MEM_POSTGRES_IDLE_TIMEOUT_MS, DEFAULT_IDLE_TIMEOUT_MS),
connectionTimeoutMillis: parsePositiveInt(env.CLAUDE_MEM_POSTGRES_CONNECTION_TIMEOUT_MS, DEFAULT_CONNECTION_TIMEOUT_MS),
statementTimeoutMillis: parsePositiveInt(env.CLAUDE_MEM_POSTGRES_STATEMENT_TIMEOUT_MS, DEFAULT_STATEMENT_TIMEOUT_MS),
ssl: parseSsl(connectionString, env)
};
}
function parsePositiveInt(value: string | undefined, fallback: number): number {
if (!value) {
return fallback;
}View on GitHub (pinned to d8bc9755e7)