thedotmack/claude-mem · error
CLAUDE_MEM_QUEUE_ENGINE is not "bullmq"
Error message
CLAUDE_MEM_QUEUE_ENGINE is not "bullmq"
What it means
collectBullmqCounts collects BullMQ queue depth statistics by connecting to Redis, but only makes sense when the queue engine is actually BullMQ. It throws this guard error when getRedisQueueConfig().engine is not 'bullmq', protecting against querying BullMQ queues on an installation configured for a different engine.
Solutions
- Set CLAUDE_MEM_QUEUE_ENGINE=bullmq in the environment or server config.
- If you intentionally use another engine, use the job-count tooling that matches your engine instead of the BullMQ path.
- Remove a stale CLAUDE_MEM_QUEUE_ENGINE value so the default engine is used.
Example fix
// before CLAUDE_MEM_QUEUE_ENGINE=inline claude-mem server-jobs // after CLAUDE_MEM_QUEUE_ENGINE=bullmq claude-mem server-jobs
Defensive patterns
Strategy: validation
Validate before calling
const config = await getRedisQueueConfig();
if (config.engine !== 'bullmq') {
console.warn('Job-count tooling requires CLAUDE_MEM_QUEUE_ENGINE=bullmq');
return;
} Type guard
const isBullmq = (c: { engine: string }): c is { engine: 'bullmq' } => c.engine === 'bullmq'; Try / catch
try {
const counts = await collectBullmqCounts();
} catch (e) {
if (String(e).includes('not "bullmq"')) {
console.error('Queue engine is not bullmq; use the matching jobs tooling.');
}
} Prevention
- Keep CLAUDE_MEM_QUEUE_ENGINE consistent across environments (dotfiles, CI, containers).
- Gate jobs-inspection UI/commands on the configured engine before calling them.
- Document the env var in deployment configs.
When it happens
Trigger: Calling the server-jobs command (which invokes collectBullmqCounts) while CLAUDE_MEM_QUEUE_ENGINE (or equivalent config) resolves to a non-bullmq engine in getRedisQueueConfig().
Common situations: Developer switched the queue engine to a non-BullMQ implementation but still runs jobs-inspection tooling that assumes BullMQ; stale environment variable from an older setup.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- ActiveServerQueueManager requires…
- BullMQ re-enqueue failed (will reconcile on startup)
- CLAUDE_MEM_TELEGRAM_WRAPUP_ROUTES must be a JSON object
- Corrupt JSON file, refusing to overwrite
- Empty observation response, leaving queue intact
AI-assisted analysis of thedotmack/claude-mem@d8bc9755e7 (2026-09-17).
Data as JSON: /api/errors/4cb66a0492f205df.
Report an issue: GitHub.
Appendix: source
Thrown at src/npx-cli/commands/server-jobs.ts:511
}> {
if (testSeams.openPool) return testSeams.openPool();
const { getSharedPostgresPool } = await import('../../storage/postgres/index.js');
const pool = getSharedPostgresPool({ requireDatabaseUrl: true });
return {
pool: pool as never,
releasePool: async () => { /* shared pool tears down on process exit */ },
};
}
// BullMQ access. Direct construction avoids importing the runtime, keeping
// the CLI fast to boot. Returns counts per known queue name; gracefully
// returns null when Redis is unconfigured.
async function collectBullmqCounts(): Promise<Record<string, { waiting: number; active: number; completed: number; failed: number; delayed: number; stalled: number }>> {
const { getRedisQueueConfig } = await import('../../server/queue/redis-config.js');
const { Queue } = await import('bullmq');
const config = getRedisQueueConfig();
if (config.engine !== 'bullmq') {
throw new Error('CLAUDE_MEM_QUEUE_ENGINE is not "bullmq"');
}
const { SERVER_JOB_QUEUE_NAMES } = await import('../../server/jobs/types.js');
const out: Record<string, { waiting: number; active: number; completed: number; failed: number; delayed: number; stalled: number }> = {};
for (const [kind, name] of Object.entries(SERVER_JOB_QUEUE_NAMES)) {
const queue = new Queue(name, { connection: config.connection, prefix: config.prefix });
try {
const counts = await queue.getJobCounts('waiting', 'active', 'completed', 'failed', 'delayed');
out[kind] = {
waiting: Number(counts.waiting ?? 0),
active: Number(counts.active ?? 0),
completed: Number(counts.completed ?? 0),
failed: Number(counts.failed ?? 0),
delayed: Number(counts.delayed ?? 0),
stalled: 0, // BullMQ rotates the stalled list; runtime tracks it via QueueEvents.
};
} finally {
await queue.close();
}View on GitHub (pinned to d8bc9755e7)