thedotmack/claude-mem · error · Error
`server ` is a server runtime command, but…
Error message
`server ${commandLabel}` is a server runtime command, but CLAUDE_MEM_RUNTIME=${runtime}. Set CLAUDE_MEM_RUNTIME=server (and CLAUDE_MEM_SERVER_DATABASE_URL) to run server operations, or use the worker CLI (`worker-service ...`) for the worker runtime. What it means
assertServerRuntimeForCli() guards `server <cmd>` CLI subcommands so they fail fast with actionable text instead of crashing later with an opaque Postgres pool error. It throws when CLAUDE_MEM_RUNTIME is set to a non-server value (typically 'worker'); the canonical 'server' and the legacy 'server-beta' literal are both accepted (Phase 1d dual-accept).
Solutions
- Export CLAUDE_MEM_RUNTIME=server (and CLAUDE_MEM_SERVER_DATABASE_URL) in the shell before running `server` subcommands.
- If this machine is worker-only, use the worker CLI (`worker-service ...`) for worker-runtime operations instead.
- Scope CLAUDE_MEM_RUNTIME=worker per-command rather than globally so it does not leak into server commands.
- Remember 'server-beta' still works if your existing config uses it.
Example fix
# before export CLAUDE_MEM_RUNTIME=worker claude-mem server api-key create # after export CLAUDE_MEM_RUNTIME=server export CLAUDE_MEM_SERVER_DATABASE_URL=postgres://... claude-mem server api-key create
Defensive patterns
Strategy: validation
Validate before calling
const runtime = (process.env.CLAUDE_MEM_RUNTIME ?? '').trim().toLowerCase();
if (runtime && runtime !== 'server' && runtime !== 'server-beta') {
throw new Error(
`Refusing to run server commands with CLAUDE_MEM_RUNTIME=${runtime}; ` +
'set CLAUDE_MEM_RUNTIME=server or unset it',
);
} Type guard
function isServerRuntimeLiteral(v: string): boolean {
const t = v.trim().toLowerCase();
return t === '' || t === 'server' || t === 'server-beta';
} Prevention
- Keep two distinct shell/env contexts: one for worker operation, one for server admin commands.
- Scope CLAUDE_MEM_RUNTIME=worker to the specific worker processes instead of exporting it globally.
- Note both 'server' and legacy 'server-beta' are accepted; anything else (including 'worker') blocks server subcommands.
When it happens
Trigger: Running `claude-mem server api-key create` (or any server subcommand) in a shell where CLAUDE_MEM_RUNTIME=worker is exported — e.g. the same environment used for worker/service operation; CI images that default the variable to worker; .env files shared between worker and server contexts.
Common situations: Operators managing both worker and server runtimes from one machine; docker/CI environments exporting a global CLAUDE_MEM_RUNTIME; scripts written before the runtime split that assume every command works everywhere.
Related errors
- CLAUDE_MEM_SERVER_DATABASE_URL is required for `server
- server startup configuration is invalid
- Cannot bootstrap server API key…
- CLAUDE_CODE_PATH is set to
- CLAUDE_CODE_PATH is set to
AI-assisted analysis of thedotmack/claude-mem@8bc631a71a (2026-08-20).
Data as JSON: /api/errors/d6d618291ec44350.
Report an issue: GitHub.
Appendix: source
Thrown at src/server/runtime/ServerService.ts:493
// is invisible to the server runtime, which reads keys from Postgres. Use
// this entrypoint inside Docker / Compose.
// #2572 — wrong-runtime guard.
//
// The server operability commands (`api-key`, `keys`, `jobs`) only make
// sense in the server runtime, whose canonical store is Postgres. If they
// are invoked in a worker-only context — `CLAUDE_MEM_RUNTIME` set to `worker`,
// or no `CLAUDE_MEM_SERVER_DATABASE_URL` configured — we fail fast with an
// actionable message instead of crashing later with an opaque pool error.
//
// Phase 1d: dual-accept the persisted runtime literal (`'server'` is the new
// canonical form; `'server-beta'` remains valid for existing installs).
export function assertServerRuntimeForCli(
commandLabel: string,
env: NodeJS.ProcessEnv = process.env,
): void {
const runtime = (env.CLAUDE_MEM_RUNTIME ?? '').trim().toLowerCase();
if (runtime && runtime !== 'server' && runtime !== 'server-beta') {
throw new Error(
`\`server ${commandLabel}\` is a server runtime command, but CLAUDE_MEM_RUNTIME=${runtime}. ` +
'Set CLAUDE_MEM_RUNTIME=server (and CLAUDE_MEM_SERVER_DATABASE_URL) to run server operations, ' +
'or use the worker CLI (`worker-service ...`) for the worker runtime.',
);
}
if (!(env.CLAUDE_MEM_SERVER_DATABASE_URL ?? '').trim()) {
throw new Error(
`CLAUDE_MEM_SERVER_DATABASE_URL is required for \`server ${commandLabel}\`. ` +
'This command talks to the server Postgres backend; export the connection string before running it.',
);
}
}
export async function runServerApiKeyCli(argv: string[]): Promise<void> {
const sub = argv[0]?.toLowerCase();
const options = parseFlagArgs(argv.slice(1));
try {View on GitHub (pinned to 8bc631a71a)