{"record":{"id":"4cb66a0492f205df","repo":"thedotmack/claude-mem","slug":"claude-mem-queue-engine-is-not-bullmq","errorCode":null,"errorMessage":"CLAUDE_MEM_QUEUE_ENGINE is not \"bullmq\"","messagePattern":"CLAUDE_MEM_QUEUE_ENGINE is not \"bullmq\"","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/npx-cli/commands/server-jobs.ts","lineNumber":511,"sourceCode":"}> {\n  if (testSeams.openPool) return testSeams.openPool();\n  const { getSharedPostgresPool } = await import('../../storage/postgres/index.js');\n  const pool = getSharedPostgresPool({ requireDatabaseUrl: true });\n  return {\n    pool: pool as never,\n    releasePool: async () => { /* shared pool tears down on process exit */ },\n  };\n}\n\n// BullMQ access. Direct construction avoids importing the runtime, keeping\n// the CLI fast to boot. Returns counts per known queue name; gracefully\n// returns null when Redis is unconfigured.\nasync function collectBullmqCounts(): Promise<Record<string, { waiting: number; active: number; completed: number; failed: number; delayed: number; stalled: number }>> {\n  const { getRedisQueueConfig } = await import('../../server/queue/redis-config.js');\n  const { Queue } = await import('bullmq');\n  const config = getRedisQueueConfig();\n  if (config.engine !== 'bullmq') {\n    throw new Error('CLAUDE_MEM_QUEUE_ENGINE is not \"bullmq\"');\n  }\n  const { SERVER_JOB_QUEUE_NAMES } = await import('../../server/jobs/types.js');\n  const out: Record<string, { waiting: number; active: number; completed: number; failed: number; delayed: number; stalled: number }> = {};\n  for (const [kind, name] of Object.entries(SERVER_JOB_QUEUE_NAMES)) {\n    const queue = new Queue(name, { connection: config.connection, prefix: config.prefix });\n    try {\n      const counts = await queue.getJobCounts('waiting', 'active', 'completed', 'failed', 'delayed');\n      out[kind] = {\n        waiting: Number(counts.waiting ?? 0),\n        active: Number(counts.active ?? 0),\n        completed: Number(counts.completed ?? 0),\n        failed: Number(counts.failed ?? 0),\n        delayed: Number(counts.delayed ?? 0),\n        stalled: 0, // BullMQ rotates the stalled list; runtime tracks it via QueueEvents.\n      };\n    } finally {\n      await queue.close();\n    }","sourceCodeStart":493,"sourceCodeEnd":529,"githubUrl":"https://github.com/thedotmack/claude-mem/blob/d768ba364302d12b76e69e4f021f0bb1d2d50ed6/src/npx-cli/commands/server-jobs.ts#L493-L529","documentation":"Thrown by collectBullmqCounts() in the server-jobs command when getRedisQueueConfig().engine is any value other than 'bullmq'. The function constructs live BullMQ Queue objects against the configured Redis connection, which is only valid under the bullmq engine; calling it under the in-memory engine would produce misleading counts or connection errors. It is a hard precondition guard before touching BullMQ APIs.","triggerScenarios":"Running `claude-mem server-jobs` (or any caller of collectBullmqCounts) when CLAUDE_MEM_QUEUE_ENGINE is unset (defaulting to memory), set to 'memory', or set to any non-bullmq value. Also when Redis config resolution falls back because REDIS_URL is absent.","commonSituations":"Local dev without Redis, where the queue engine defaults to in-memory. A deployment that intentionally uses the memory engine but the CLI command assumes BullMQ. An env where REDIS_URL was expected but not exported, so getRedisQueueConfig returns a non-bullmq config.","solutions":["Set CLAUDE_MEM_QUEUE_ENGINE=bullmq and provide a reachable REDIS_URL, then retry.","If you did not intend to use BullMQ, do not invoke the BullMQ-specific counts path — use the memory-engine equivalent or omit the call.","Verify Redis is reachable and getRedisQueueConfig() returns engine='bullmq' before calling collectBullmqCounts()."],"exampleFix":"// before — calling BullMQ counts unconditionally\nconst counts = await collectBullmqCounts()\n// after — guard on the engine first\nconst config = getRedisQueueConfig()\nconst counts = config.engine === 'bullmq' ? await collectBullmqCounts() : {}","handlingStrategy":"type-guard","validationCode":"const config = getRedisQueueConfig();\nif (config.engine !== 'bullmq') return {}; // not a BullMQ deployment\nconst counts = await collectBullmqCounts();","typeGuard":"function isBullmqEngine(config: { engine: string }): boolean {\n  return config.engine === 'bullmq';\n}","tryCatchPattern":"try {\n  return await collectBullmqCounts();\n} catch (e) {\n  if (e instanceof Error && e.message.includes('not \"bullmq\"')) return {}; // memory engine\n  throw e;\n}","preventionTips":["Gate BullMQ-specific calls on getRedisQueueConfig().engine === 'bullmq'.","Set CLAUDE_MEM_QUEUE_ENGINE and REDIS_URL consistently in deployments that need BullMQ.","Provide a memory-engine fallback path for local/non-Redis environments."],"tags":["queue","config","redis","bullmq","validation"],"backgroundTag":null,"analyzedSha":"d768ba364302d12b76e69e4f021f0bb1d2d50ed6","analyzedAt":"2026-08-12T23:52:55.241Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}