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

  1. Set CLAUDE_MEM_SERVER_DATABASE_URL to a valid postgres:// connection string in the environment before starting the server
  2. If Postgres is optional, call parsePostgresConfig without requireDatabaseUrl and handle the null return (fall back to SQLite)
  3. 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)
  4. 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

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


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)