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

  1. Set CLAUDE_MEM_QUEUE_ENGINE=sqlite (default, no Redis needed) or CLAUDE_MEM_QUEUE_ENGINE=bullmq in your environment/.env
  2. Remove surrounding quotes or stray whitespace from the value in .env / shell exports
  3. If you meant to use Redis-based queuing, verify the exact spelling 'bullmq'
  4. 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

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


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)