{"record":{"id":"14aa82466c9f2e36","repo":"thedotmack/claude-mem","slug":"postgres-requires-claude-mem-server-database-url","errorCode":null,"errorMessage":"Postgres requires CLAUDE_MEM_SERVER_DATABASE_URL","messagePattern":"Postgres requires CLAUDE_MEM_SERVER_DATABASE_URL","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/storage/postgres/config.ts","lineNumber":32,"sourceCode":"  env?: NodeJS.ProcessEnv;\n  requireDatabaseUrl?: boolean;\n}\n\nconst DEFAULT_POOL_MAX = 10;\nconst DEFAULT_IDLE_TIMEOUT_MS = 30_000;\nconst DEFAULT_CONNECTION_TIMEOUT_MS = 5_000;\nconst DEFAULT_STATEMENT_TIMEOUT_MS = 30_000;\n\nexport function getPostgresDatabaseUrl(env: NodeJS.ProcessEnv = process.env): string | null {\n  return env.CLAUDE_MEM_SERVER_DATABASE_URL || null;\n}\n\nexport function parsePostgresConfig(options: ParsePostgresConfigOptions = {}): PostgresConfig | null {\n  const env = options.env ?? process.env;\n  const connectionString = getPostgresDatabaseUrl(env);\n  if (!connectionString) {\n    if (options.requireDatabaseUrl) {\n      throw new Error('Postgres requires CLAUDE_MEM_SERVER_DATABASE_URL');\n    }\n    return null;\n  }\n\n  return {\n    connectionString,\n    max: parsePositiveInt(env.CLAUDE_MEM_POSTGRES_POOL_MAX, DEFAULT_POOL_MAX),\n    idleTimeoutMillis: parsePositiveInt(env.CLAUDE_MEM_POSTGRES_IDLE_TIMEOUT_MS, DEFAULT_IDLE_TIMEOUT_MS),\n    connectionTimeoutMillis: parsePositiveInt(env.CLAUDE_MEM_POSTGRES_CONNECTION_TIMEOUT_MS, DEFAULT_CONNECTION_TIMEOUT_MS),\n    statementTimeoutMillis: parsePositiveInt(env.CLAUDE_MEM_POSTGRES_STATEMENT_TIMEOUT_MS, DEFAULT_STATEMENT_TIMEOUT_MS),\n    ssl: parseSsl(connectionString, env)\n  };\n}\n\nfunction parsePositiveInt(value: string | undefined, fallback: number): number {\n  if (!value) {\n    return fallback;\n  }","sourceCodeStart":14,"sourceCodeEnd":50,"githubUrl":"https://github.com/thedotmack/claude-mem/blob/d8bc9755e74915e5c3b999181e10a67c889bce2a/src/storage/postgres/config.ts#L14-L50","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nconst config = parsePostgresConfig({ env: process.env, requireDatabaseUrl: true });\n// after\nprocess.env.CLAUDE_MEM_SERVER_DATABASE_URL ??= 'postgres://user:pass@localhost:5432/claude_mem';\nconst config = parsePostgresConfig({ env: process.env, requireDatabaseUrl: true });","handlingStrategy":"validation","validationCode":"const url = process.env.CLAUDE_MEM_SERVER_DATABASE_URL;\nif (!url || !url.startsWith('postgres')) throw new Error('CLAUDE_MEM_SERVER_DATABASE_URL must be set to a postgres:// URL before enabling Postgres');","typeGuard":"function hasPostgresUrl(env: NodeJS.ProcessEnv): env is NodeJS.ProcessEnv & { CLAUDE_MEM_SERVER_DATABASE_URL: string } {\n  return typeof env.CLAUDE_MEM_SERVER_DATABASE_URL === 'string' && env.CLAUDE_MEM_SERVER_DATABASE_URL.length > 0;\n}","tryCatchPattern":"try {\n  config = parsePostgresConfig({ requireDatabaseUrl: true });\n} catch (err) {\n  if (err instanceof Error && err.message.includes('CLAUDE_MEM_SERVER_DATABASE_URL')) {\n    console.error('Missing CLAUDE_MEM_SERVER_DATABASE_URL; check your environment/.env');\n    process.exit(1);\n  }\n  throw err;\n}","preventionTips":["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"],"tags":["postgres","configuration","env-var"],"backgroundTag":"missing-env-var","analyzedSha":"d8bc9755e74915e5c3b999181e10a67c889bce2a","analyzedAt":"2026-09-17T16:40:26.182Z","contentChangedAt":"2026-09-17T16:40:26.182Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}