thedotmack/claude-mem · error
Invalid CLAUDE_MEM_QUEUE_ENGINE=
Error message
Invalid CLAUDE_MEM_QUEUE_ENGINE=${raw}; expected sqlite or bullmq What it means
This error is thrown by getObservationQueueEngineName when the CLAUDE_MEM_QUEUE_ENGINE environment variable contains a value other than 'sqlite' or 'bullmq' (case-insensitive, after trimming). claude-mem uses this variable to select the observation queue backend, and it refuses to start with an unknown engine name rather than silently defaulting. The raw, unnormalized value is interpolated into the message so you can see exactly what was read.
Solutions
- Set CLAUDE_MEM_QUEUE_ENGINE=sqlite (default, no Redis needed) or CLAUDE_MEM_QUEUE_ENGINE=bullmq in your environment/.env
- Remove surrounding quotes or stray whitespace from the value in .env / shell exports
- If you meant to use Redis-based queuing, verify the exact spelling 'bullmq'
- If the variable is not needed, unset it entirely so defaults apply
Example fix
// before (.env) CLAUDE_MEM_QUEUE_ENGINE=redis // after CLAUDE_MEM_QUEUE_ENGINE=bullmq
Defensive patterns
Strategy: validation
Validate before calling
const ALLOWED = ['sqlite','bullmq'];
const raw = (process.env.CLAUDE_MEM_QUEUE_ENGINE ?? '').trim().toLowerCase();
if (!ALLOWED.includes(raw)) {
throw new Error(`CLAUDE_MEM_QUEUE_ENGINE must be one of ${ALLOWED.join(', ')}; got "${raw}"`);
} Type guard
function isObservationQueueEngine(v: string): v is 'sqlite' | 'bullmq' {
return v === 'sqlite' || v === 'bullmq';
} Try / catch
try {
startQueue();
} catch (err) {
if (err instanceof Error && err.message.includes('CLAUDE_MEM_QUEUE_ENGINE')) {
console.error('Fix CLAUDE_MEM_QUEUE_ENGINE in your env: use sqlite or bullmq', err.message);
process.exit(1);
}
throw err;
} Prevention
- Keep allowed values in one shared constant and validate env at startup with a schema library (zod, envalid)
- Never quote values inside .env files unless your loader strips quotes
- Document the exact accepted strings next to the variable in your deploy templates
- Fail fast: run env validation as the first step of your app, not at first queue use
When it happens
Trigger: Setting CLAUDE_MEM_QUEUE_ENGINE to any string other than 'sqlite' or 'bullmq' — e.g. 'redis', 'sqlite3', 'SQLite ' is fine after trim/lowercase, but 'redis', '', a typo like 'bullm', or a quoted '"sqlite"' value all throw. Called indirectly whenever getRedisQueueConfig()/engine selection runs during queue initialization.
Common situations: Typo'ing the engine name in .env or docker-compose; copying config from an older version that allowed other engines; leaving the variable set to an empty or placeholder value like 'CHANGE_ME'; exporting it with surrounding quotes or whitespace embedded in the value from CI secret managers.
Understand the failure class
Background: "is not a valid" / "Invalid ... value" environment variable errors: how libraries validate env vars and what to do when they reject yours — this error's family across 48 libraries.
Related errors
- Invalid CLAUDE_MEM_REDIS_MODE=
- Invalid CLAUDE_MEM_REDIS_PORT=
- server startup configuration is invalid:
- CLAUDE_MEM_REDIS_URL must use redis:// or rediss://
- Invalid Redis database in CLAUDE_MEM_REDIS_URL
AI-assisted analysis of thedotmack/claude-mem@d8bc9755e7 (2026-09-17).
Data as JSON: /api/errors/617c76e37399c96b.
Report an issue: GitHub.
Appendix: source
Thrown at src/server/queue/redis-config.ts:27
export type ObservationQueueEngineName = 'sqlite' | 'bullmq';
export type RedisMode = 'external' | 'managed' | 'docker';
export interface RedisQueueConfig {
engine: ObservationQueueEngineName;
mode: RedisMode;
url: string | null;
host: string;
port: number;
prefix: string;
connection: RedisOptions;
}
export function getObservationQueueEngineName(): ObservationQueueEngineName {
const raw = getQueueSetting('CLAUDE_MEM_QUEUE_ENGINE').trim().toLowerCase();
if (raw === 'sqlite' || raw === 'bullmq') {
return raw;
}
throw new Error(`Invalid CLAUDE_MEM_QUEUE_ENGINE=${raw}; expected sqlite or bullmq`);
}
export function getRedisQueueConfig(): RedisQueueConfig {
const engine = getObservationQueueEngineName();
const mode = normalizeRedisMode(getQueueSetting('CLAUDE_MEM_REDIS_MODE'));
const url = getQueueSetting('CLAUDE_MEM_REDIS_URL').trim() || null;
const host = getQueueSetting('CLAUDE_MEM_REDIS_HOST').trim() || '127.0.0.1';
const port = parseRedisPort(getQueueSetting('CLAUDE_MEM_REDIS_PORT'));
const prefix = sanitizePrefix(getQueueSetting('CLAUDE_MEM_QUEUE_REDIS_PREFIX'));
const connection = url ? connectionFromUrl(url) : connectionFromHost(host, port);
return {
engine,
mode,
url,
host: url ? describeUrlHost(url).host : host,
port: url ? describeUrlHost(url).port : port,
prefix,View on GitHub (pinned to d8bc9755e7)