{"record":{"id":"2e8f960491676741","repo":"thedotmack/claude-mem","slug":"invalid-claude-mem-redis-mode-value-expected-e","errorCode":null,"errorMessage":"Invalid CLAUDE_MEM_REDIS_MODE=${value}; expected external, managed, or docker","messagePattern":"Invalid CLAUDE_MEM_REDIS_MODE=(.+?); expected external, managed, or docker","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/server/queue/redis-config.ts","lineNumber":68,"sourceCode":"function getQueueSetting(key: keyof SettingsDefaults): string {\n  if (process.env[key] !== undefined) {\n    return process.env[key]!;\n  }\n  if (existsSync(USER_SETTINGS_PATH)) {\n    const value = SettingsDefaultsManager.loadFromFile(USER_SETTINGS_PATH, false)[key];\n    if (value !== undefined) {\n      return value;\n    }\n  }\n  return SettingsDefaultsManager.get(key);\n}\n\nfunction normalizeRedisMode(value: string): RedisMode {\n  const normalized = value.trim().toLowerCase();\n  if (normalized === 'external' || normalized === 'managed' || normalized === 'docker') {\n    return normalized;\n  }\n  throw new Error(`Invalid CLAUDE_MEM_REDIS_MODE=${value}; expected external, managed, or docker`);\n}\n\nfunction parseRedisPort(value: string): number {\n  const port = Number.parseInt(value, 10);\n  if (!Number.isInteger(port) || port <= 0 || port > 65535) {\n    throw new Error(`Invalid CLAUDE_MEM_REDIS_PORT=${value}; expected a TCP port`);\n  }\n  return port;\n}\n\nfunction sanitizePrefix(value: string): string {\n  return (value.trim() || 'claude_mem').replace(/[^a-zA-Z0-9_-]/g, '_');\n}\n\nfunction connectionFromHost(host: string, port: number): RedisOptions {\n  return {\n    host,\n    port,","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/thedotmack/claude-mem/blob/d8bc9755e74915e5c3b999181e10a67c889bce2a/src/server/queue/redis-config.ts#L50-L86","documentation":"Thrown by normalizeRedisMode when CLAUDE_MEM_REDIS_MODE is not one of 'external', 'managed', or 'docker' (compared case-insensitively after trimming). This variable tells claude-mem how its Redis instance is provisioned so it can apply the right connection behavior. The library fails fast with the offending raw value rather than guessing a mode.","triggerScenarios":"Setting CLAUDE_MEM_REDIS_MODE to anything else: '', 'local', 'standalone', 'cluster', 'EXTERNAL ' is OK after normalization, but 'External:' with punctuation, 'self-hosted', or a boolean-like 'true' all throw. Triggered during getRedisQueueConfig() while resolving queue settings.","commonSituations":"Copy-pasting Redis config from another project that uses different mode names; inventing a plausible mode like 'standalone'; leaving the key present but empty in .env; a deploy tool that injects the variable as an empty string.","solutions":["Set CLAUDE_MEM_REDIS_MODE to exactly one of: external, managed, docker","Remove the variable entirely if Redis mode should be defaulted/absent","Check for empty values produced by secret managers or docker-compose env interpolation and fix them","Fix typos like 'extrenal' or 'docke' — spelling must match exactly after lowercasing"],"exampleFix":"// before (.env)\nCLAUDE_MEM_REDIS_MODE=standalone\n// after\nCLAUDE_MEM_REDIS_MODE=external","handlingStrategy":"validation","validationCode":"const MODES = ['external','managed','docker'];\nconst mode = (process.env.CLAUDE_MEM_REDIS_MODE ?? '').trim().toLowerCase();\nif (!MODES.includes(mode)) {\n  throw new Error(`CLAUDE_MEM_REDIS_MODE must be one of ${MODES.join(', ')}; got \"${mode}\"`);\n}","typeGuard":"function isRedisMode(v: string): v is 'external' | 'managed' | 'docker' {\n  return v === 'external' || v === 'managed' || v === 'docker';\n}","tryCatchPattern":"try {\n  const config = getRedisQueueConfig();\n} catch (err) {\n  if (err instanceof Error && err.message.includes('CLAUDE_MEM_REDIS_MODE')) {\n    console.error('CLAUDE_MEM_REDIS_MODE must be external, managed, or docker:', err.message);\n  }\n  throw err;\n}","preventionTips":["Use a zod enum schema for all CLAUDE_MEM_* env vars at boot","Avoid inventing mode names; consult the docs list (external/managed/docker) before adding config","Watch for empty-string injection from orchestrators (docker-compose, k8s ConfigMaps) and omit the key instead","Add an env sanity check script to CI so bad values fail before deployment"],"tags":["configuration","environment","redis","validation"],"backgroundTag":"invalid-env-var-value","analyzedSha":"d8bc9755e74915e5c3b999181e10a67c889bce2a","analyzedAt":"2026-09-17T16:40:26.182Z","contentChangedAt":"2026-09-17T16:40:26.182Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}