thedotmack/claude-mem · critical
server startup configuration is invalid:
Error message
server startup configuration is invalid:
What it means
validateServerEnv performs fail-fast environment validation before the claude-mem server can start. It aggregates every invalid combination of CLAUDE_MEM_* variables (runtime, auth mode, queue engine, database URL, Redis URL) — with stricter rules when a Docker environment is detected — and throws a single Error whose message is a bulleted list of all problems found. The multi-line format lets operators fix every issue in one restart instead of discovering them one at a time.
Solutions
- Read the bulleted list in the error message — each line names exactly one env variable to fix.
- Set CLAUDE_MEM_SERVER_DATABASE_URL to a valid Postgres connection string (always required).
- In Docker: set CLAUDE_MEM_QUEUE_ENGINE=bullmq and CLAUDE_MEM_REDIS_URL to your Redis instance.
- In Docker: set CLAUDE_MEM_RUNTIME=server (or legacy server-beta) and CLAUDE_MEM_AUTH_MODE=api-key; create a key with `claude-mem server api-key create`; remove CLAUDE_MEM_ALLOW_LOCAL_DEV_BYPASS.
- For local development outside Docker, keep local-dev auth/bypass settings but ensure the database URL is still provided.
Example fix
// before (docker-compose env, fails) CLAUDE_MEM_RUNTIME=worker CLAUDE_MEM_AUTH_MODE=local-dev CLAUDE_MEM_QUEUE_ENGINE= # after CLAUDE_MEM_RUNTIME=server CLAUDE_MEM_AUTH_MODE=api-key CLAUDE_MEM_QUEUE_ENGINE=bullmq CLAUDE_MEM_REDIS_URL=redis://redis:6379 CLAUDE_MEM_SERVER_DATABASE_URL=postgres://user:pass@db:5432/claude_mem
Defensive patterns
Strategy: validation
Validate before calling
const required = ['CLAUDE_MEM_SERVER_DATABASE_URL'];
const docker = process.env.DOCKER_BUILD != null || process.env.container != null; // container detection
if (docker) required.push('CLAUDE_MEM_QUEUE_ENGINE', 'CLAUDE_MEM_REDIS_URL');
const missing = required.filter(k => !(process.env[k] ?? '').trim());
if (missing.length) throw new Error(`missing server env: ${missing.join(', ')}`);
const rt = (process.env.CLAUDE_MEM_RUNTIME ?? '').trim();
if (docker && rt && rt !== 'server' && rt !== 'server-beta') throw new Error(`invalid CLAUDE_MEM_RUNTIME=${rt} in Docker`); Try / catch
try {
const service = await createServerService();
} catch (err) {
if ((err as Error).message.startsWith('server startup configuration is invalid:')) {
// print each ' - ' line as a separate ops remediation item and abort boot
}
throw err;
} Prevention
- Keep a single .env template for server deployments listing every CLAUDE_MEM_* variable with required markers.
- Validate env at CI/container-build time (docker compose config + a startup healthcheck) rather than at runtime boot.
- Never copy local-dev env files into Docker deployments; keep them in separate, named files.
- After switching queue engine to bullmq, immediately pair it with CLAUDE_MEM_REDIS_URL.
When it happens
Trigger: Calling createServerService() or runServerGenerationWorker() when: CLAUDE_MEM_RUNTIME is set to something other than 'server'/'server-beta' inside Docker; CLAUDE_MEM_AUTH_MODE=local-dev in Docker; CLAUDE_MEM_ALLOW_LOCAL_DEV_BYPASS=1|true in Docker; CLAUDE_MEM_QUEUE_ENGINE missing or not 'bullmq' in Docker; CLAUDE_MEM_SERVER_DATABASE_URL unset; or CLAUDE_MEM_REDIS_URL unset while queue engine is bullmq.
Common situations: Starting the server container with a docker-compose env copied from a local-dev setup (local-dev auth, missing queue engine); forgetting CLAUDE_MEM_SERVER_DATABASE_URL after migrating to Postgres; leaving CLAUDE_MEM_RUNTIME=worker on the server image; running bullmq without a Redis URL; legacy scripts still exporting server-beta or the local-dev bypass flags.
Understand the failure class
Background: "X is required", "must be set", "cannot be empty": the missing-required-config error family, from Vertex AI project/location to WeChat keys — this error's family across 18 libraries.
Related errors
- server startup configuration is invalid
- Invalid CLAUDE_MEM_QUEUE_ENGINE=
- Invalid CLAUDE_MEM_REDIS_MODE=
- Invalid CLAUDE_MEM_REDIS_PORT=
- CLAUDE_MEM_REDIS_URL must use redis:// or rediss://
AI-assisted analysis of thedotmack/claude-mem@d8bc9755e7 (2026-09-17).
Data as JSON: /api/errors/4726436c87daf29e.
Report an issue: GitHub.
Appendix: source
Thrown at src/server/runtime/create-server-service.ts:144
}
}
const hasDatabaseUrl = Boolean((env.CLAUDE_MEM_SERVER_DATABASE_URL ?? '').trim());
if (!hasDatabaseUrl) {
errors.push('CLAUDE_MEM_SERVER_DATABASE_URL is required to start the server (Postgres connection string).');
}
const hasRedisUrl = Boolean((env.CLAUDE_MEM_REDIS_URL ?? '').trim());
if (queueEngine === 'bullmq' && !hasRedisUrl) {
errors.push('CLAUDE_MEM_REDIS_URL is required when CLAUDE_MEM_QUEUE_ENGINE=bullmq.');
}
if (errors.length > 0) {
const message = [
'server startup configuration is invalid:',
...errors.map(line => ` - ${line}`),
].join('\n');
throw new Error(message);
}
return {
isDocker,
// Phase 1a: report the canonical `'server'` value when unset; legacy
// `'server-beta'` is preserved verbatim when explicitly supplied so
// diagnostics reflect the operator's actual config.
runtime: runtime || 'server',
authMode,
queueEngine: queueEngine || 'disabled',
hasDatabaseUrl,
hasRedisUrl,
};
}
// #2443 — the server runtime must load an observation mode before it can
// process any generation job; without it every job fails with "No mode
// loaded". We mirror the worker's pattern (src/services/worker-service.ts) andView on GitHub (pinned to d8bc9755e7)