thedotmack/claude-mem · critical

Postgres requires CLAUDE_MEM_SERVER_DATABASE_URL

Error message

Postgres requires CLAUDE_MEM_SERVER_DATABASE_URL

What it means

Thrown by getSharedPostgresPool (via parsePostgresConfig) when CLAUDE_MEM_SERVER_DATABASE_URL is unset/empty and requireDatabaseUrl is true (the default). The pool cannot be created without a connection string, so any path that needs Postgres fails immediately at startup.

Source

Thrown at src/storage/postgres/pool.ts:31

export function createPostgresPool(config: PostgresConfig): PostgresPool {
  return new Pool({
    connectionString: config.connectionString,
    max: config.max,
    idleTimeoutMillis: config.idleTimeoutMillis,
    connectionTimeoutMillis: config.connectionTimeoutMillis,
    statement_timeout: config.statementTimeoutMillis,
    ssl: config.ssl
  });
}

export function getSharedPostgresPool(options: { requireDatabaseUrl?: boolean } = {}): PostgresPool {
  if (sharedPool) {
    return sharedPool;
  }
  const config = parsePostgresConfig({ requireDatabaseUrl: options.requireDatabaseUrl ?? true });
  if (!config) {
    throw new Error('Postgres requires CLAUDE_MEM_SERVER_DATABASE_URL');
  }
  sharedPool = createPostgresPool(config);
  return sharedPool;
}

export async function withPostgresTransaction<T>(
  pool: PostgresPool,
  fn: (client: PostgresPoolClient) => Promise<T>
): Promise<T> {
  const client = await pool.connect();
  try {
    await client.query('BEGIN');
    const result = await fn(client);
    await client.query('COMMIT');
    return result;
  } catch (error) {
    const err = error instanceof Error ? error : new Error(String(error));
    logger.warn('DB', 'Postgres transaction rolled back', {}, err);

View on GitHub (pinned to d768ba3643)

Solutions

  1. Set CLAUDE_MEM_SERVER_DATABASE_URL to a valid postgres:// connection string in the environment (.env, docker env, CI secrets).
  2. If Postgres is optional for this code path, call getSharedPostgresPool({requireDatabaseUrl:false}) and handle the null config gracefully.
  3. Verify the variable is actually exported to the process (print process.env keys, not the value).

Example fix

# before
# .env missing the var
# after (.env)
CLAUDE_MEM_SERVER_DATABASE_URL=postgres://user:pass@localhost:5432/claude_mem
Defensive patterns

Strategy: validation

Validate before calling

if (!process.env.CLAUDE_MEM_SERVER_DATABASE_URL) {
  console.error('CLAUDE_MEM_SERVER_DATABASE_URL is required');
  process.exit(1);
}

Type guard

function hasDatabaseUrl(env = process.env){ return Boolean(env.CLAUDE_MEM_SERVER_DATABASE_URL); }

Try / catch

try { pool = getSharedPostgresPool(); } catch (e) { if (e.message==='Postgres requires CLAUDE_MEM_SERVER_DATABASE_URL') { /* degrade or exit */ } else throw e; }

Prevention

When it happens

Trigger: Booting the server/worker without CLAUDE_MEM_SERVER_DATABASE_URL set in the environment, or calling getSharedPostgresPool() with the default options when the env var is missing. Empty string is treated as missing.

Common situations: Missing .env in local dev, forgotten env var in CI or container, typo in variable name, deploying without provisioning the DB, or a wrapper script not exporting the variable.

Related errors


AI-assisted analysis of thedotmack/claude-mem@d768ba3643 (2026-08-12). Data as JSON: /api/errors/23459375910f8488. Report an issue: GitHub.