thedotmack/claude-mem · error
server startup configuration is invalid: - ${line}
Error message
server startup configuration is invalid:
- ${line} What it means
Thrown by the server startup config validator (create-server-service.ts) when one or more startup checks fail. It aggregates every problem into a single bulleted list (each prefixed with '- ') covering Docker/runtime/auth/queue/database/redis constraints, then throws one combined error so the operator sees all issues at once rather than fixing them one at a time. Failure cases include: missing CLAUDE_MEM_SERVER_DATABASE_URL, invalid Docker runtime/auth/queue values, local-dev bypass in Docker, and missing CLAUDE_MEM_REDIS_URL when the queue engine is bullmq.
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 d768ba3643)
Solutions
- Read every bulleted line in the message — each is an independent fix; address all of them before restarting.
- Always set CLAUDE_MEM_SERVER_DATABASE_URL to a reachable Postgres connection string.
- If CLAUDE_MEM_QUEUE_ENGINE=bullmq, also set CLAUDE_MEM_REDIS_URL (redis:// or rediss://).
- In Docker: set CLAUDE_MEM_RUNTIME=server (or leave unset), CLAUDE_MEM_AUTH_MODE=api-key, CLAUDE_MEM_QUEUE_ENGINE=bullmq, and remove CLAUDE_MEM_ALLOW_LOCAL_DEV_BYPASS.
- Re-run startup; the validator will only pass when the errors list is empty.
Example fix
# before (Docker, incomplete): # CLAUDE_MEM_AUTH_MODE=local-dev # CLAUDE_MEM_QUEUE_ENGINE=bullmq (no REDIS_URL) # after: export CLAUDE_MEM_AUTH_MODE=api-key export CLAUDE_MEM_QUEUE_ENGINE=bullmq export CLAUDE_MEM_REDIS_URL=rediss://redis.example.com:6379 export CLAUDE_MEM_SERVER_DATABASE_URL=postgres://app:secret@db:5432/claude_mem export CLAUDE_MEM_RUNTIME=server
Defensive patterns
Strategy: validation
Validate before calling
function validateServerStartupConfig(env: NodeJS.ProcessEnv, isDocker: boolean): string[] {
const errors: string[] = [];
if (!(env.CLAUDE_MEM_SERVER_DATABASE_URL ?? '').trim()) {
errors.push('CLAUDE_MEM_SERVER_DATABASE_URL is required.');
}
const qe = (env.CLAUDE_MEM_QUEUE_ENGINE ?? '').trim().toLowerCase();
if (qe === 'bullmq' && !(env.CLAUDE_MEM_REDIS_URL ?? '').trim()) {
errors.push('CLAUDE_MEM_REDIS_URL is required when CLAUDE_MEM_QUEUE_ENGINE=bullmq.');
}
if (isDocker) {
if ((env.CLAUDE_MEM_AUTH_MODE ?? 'api-key') === 'local-dev') errors.push('local-dev not allowed in Docker');
if (qe && qe !== 'bullmq') errors.push('Only bullmq queue engine allowed in Docker');
}
return errors;
}
// call before server boot; surface all errors at once Try / catch
try {
config = resolveServerStartupConfig(env);
} catch (error) {
// message lists every problem bulleted; fix ALL of them, then restart.
console.error((error as Error).message);
process.exit(1);
} Prevention
- Centralize all required env in a single profile (systemd/Docker env/.env) and lint it before boot.
- In Docker, never carry local-dev settings (local-dev auth, allow-bypass, non-server runtime).
- When switching the queue engine to bullmq, always configure Redis in the same change.
- Treat the aggregated message as a checklist — address every bullet before restarting.
When it happens
Trigger: Starting the server with CLAUDE_MEM_SERVER_DATABASE_URL unset; CLAUDE_MEM_QUEUE_ENGINE=bullmq but no CLAUDE_MEM_REDIS_URL; in Docker, setting CLAUDE_MEM_RUNTIME to a non-server value, CLAUDE_MEM_AUTH_MODE=local-dev, CLAUDE_MEM_ALLOW_LOCAL_DEV_BYPASS=1, or CLAUDE_MEM_QUEUE_ENGINE other than bullmq/empty.
Common situations: First server boot with incomplete env. A Docker deployment missing required variables. An operator enabling bullmq without configuring Redis. Copying a local-dev env into a container.
Related errors
- CLAUDE_MEM_QUEUE_ENGINE is not "bullmq"
- Invalid CLAUDE_MEM_REDIS_MODE=${value}; expected external, m
- Invalid CLAUDE_MEM_REDIS_PORT=${value}; expected a TCP port
- CLAUDE_MEM_REDIS_URL must use redis:// or rediss://
- Invalid Redis database in CLAUDE_MEM_REDIS_URL: ${parsed.pat
AI-assisted analysis of thedotmack/claude-mem@d768ba3643 (2026-08-12).
Data as JSON: /api/errors/5a848c1dafc98a38.
Report an issue: GitHub.