{"record":{"id":"5a848c1dafc98a38","repo":"thedotmack/claude-mem","slug":"server-startup-configuration-is-invalid-lin","errorCode":null,"errorMessage":"server startup configuration is invalid:\n  - ${line}","messagePattern":"server startup configuration is invalid:\n  - (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/server/runtime/create-server-service.ts","lineNumber":144,"sourceCode":"    }\n  }\n\n  const hasDatabaseUrl = Boolean((env.CLAUDE_MEM_SERVER_DATABASE_URL ?? '').trim());\n  if (!hasDatabaseUrl) {\n    errors.push('CLAUDE_MEM_SERVER_DATABASE_URL is required to start the server (Postgres connection string).');\n  }\n\n  const hasRedisUrl = Boolean((env.CLAUDE_MEM_REDIS_URL ?? '').trim());\n  if (queueEngine === 'bullmq' && !hasRedisUrl) {\n    errors.push('CLAUDE_MEM_REDIS_URL is required when CLAUDE_MEM_QUEUE_ENGINE=bullmq.');\n  }\n\n  if (errors.length > 0) {\n    const message = [\n      'server startup configuration is invalid:',\n      ...errors.map(line => `  - ${line}`),\n    ].join('\\n');\n    throw new Error(message);\n  }\n\n  return {\n    isDocker,\n    // Phase 1a: report the canonical `'server'` value when unset; legacy\n    // `'server-beta'` is preserved verbatim when explicitly supplied so\n    // diagnostics reflect the operator's actual config.\n    runtime: runtime || 'server',\n    authMode,\n    queueEngine: queueEngine || 'disabled',\n    hasDatabaseUrl,\n    hasRedisUrl,\n  };\n}\n\n// #2443 — the server runtime must load an observation mode before it can\n// process any generation job; without it every job fails with \"No mode\n// loaded\". We mirror the worker's pattern (src/services/worker-service.ts) and","sourceCodeStart":126,"sourceCodeEnd":162,"githubUrl":"https://github.com/thedotmack/claude-mem/blob/d768ba364302d12b76e69e4f021f0bb1d2d50ed6/src/server/runtime/create-server-service.ts#L126-L162","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before (Docker, incomplete):\n#   CLAUDE_MEM_AUTH_MODE=local-dev\n#   CLAUDE_MEM_QUEUE_ENGINE=bullmq  (no REDIS_URL)\n# after:\nexport CLAUDE_MEM_AUTH_MODE=api-key\nexport CLAUDE_MEM_QUEUE_ENGINE=bullmq\nexport CLAUDE_MEM_REDIS_URL=rediss://redis.example.com:6379\nexport CLAUDE_MEM_SERVER_DATABASE_URL=postgres://app:secret@db:5432/claude_mem\nexport CLAUDE_MEM_RUNTIME=server","handlingStrategy":"validation","validationCode":"function validateServerStartupConfig(env: NodeJS.ProcessEnv, isDocker: boolean): string[] {\n  const errors: string[] = [];\n  if (!(env.CLAUDE_MEM_SERVER_DATABASE_URL ?? '').trim()) {\n    errors.push('CLAUDE_MEM_SERVER_DATABASE_URL is required.');\n  }\n  const qe = (env.CLAUDE_MEM_QUEUE_ENGINE ?? '').trim().toLowerCase();\n  if (qe === 'bullmq' && !(env.CLAUDE_MEM_REDIS_URL ?? '').trim()) {\n    errors.push('CLAUDE_MEM_REDIS_URL is required when CLAUDE_MEM_QUEUE_ENGINE=bullmq.');\n  }\n  if (isDocker) {\n    if ((env.CLAUDE_MEM_AUTH_MODE ?? 'api-key') === 'local-dev') errors.push('local-dev not allowed in Docker');\n    if (qe && qe !== 'bullmq') errors.push('Only bullmq queue engine allowed in Docker');\n  }\n  return errors;\n}\n// call before server boot; surface all errors at once","typeGuard":null,"tryCatchPattern":"try {\n  config = resolveServerStartupConfig(env);\n} catch (error) {\n  // message lists every problem bulleted; fix ALL of them, then restart.\n  console.error((error as Error).message);\n  process.exit(1);\n}","preventionTips":["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."],"tags":["config","startup","validation","docker","database","redis"],"backgroundTag":null,"analyzedSha":"d768ba364302d12b76e69e4f021f0bb1d2d50ed6","analyzedAt":"2026-08-12T23:52:55.241Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}