thedotmack/claude-mem · error

Invalid CLAUDE_MEM_REDIS_MODE=

Error message

Invalid CLAUDE_MEM_REDIS_MODE=${value}; expected external, managed, or docker

What it means

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.

Solutions

  1. Set CLAUDE_MEM_REDIS_MODE to exactly one of: external, managed, docker
  2. Remove the variable entirely if Redis mode should be defaulted/absent
  3. Check for empty values produced by secret managers or docker-compose env interpolation and fix them
  4. Fix typos like 'extrenal' or 'docke' — spelling must match exactly after lowercasing

Example fix

// before (.env)
CLAUDE_MEM_REDIS_MODE=standalone
// after
CLAUDE_MEM_REDIS_MODE=external
Defensive patterns

Strategy: validation

Validate before calling

const MODES = ['external','managed','docker'];
const mode = (process.env.CLAUDE_MEM_REDIS_MODE ?? '').trim().toLowerCase();
if (!MODES.includes(mode)) {
  throw new Error(`CLAUDE_MEM_REDIS_MODE must be one of ${MODES.join(', ')}; got "${mode}"`);
}

Type guard

function isRedisMode(v: string): v is 'external' | 'managed' | 'docker' {
  return v === 'external' || v === 'managed' || v === 'docker';
}

Try / catch

try {
  const config = getRedisQueueConfig();
} catch (err) {
  if (err instanceof Error && err.message.includes('CLAUDE_MEM_REDIS_MODE')) {
    console.error('CLAUDE_MEM_REDIS_MODE must be external, managed, or docker:', err.message);
  }
  throw err;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

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/2e8f960491676741. Report an issue: GitHub.

Appendix: source

Thrown at src/server/queue/redis-config.ts:68

function getQueueSetting(key: keyof SettingsDefaults): string {
  if (process.env[key] !== undefined) {
    return process.env[key]!;
  }
  if (existsSync(USER_SETTINGS_PATH)) {
    const value = SettingsDefaultsManager.loadFromFile(USER_SETTINGS_PATH, false)[key];
    if (value !== undefined) {
      return value;
    }
  }
  return SettingsDefaultsManager.get(key);
}

function normalizeRedisMode(value: string): RedisMode {
  const normalized = value.trim().toLowerCase();
  if (normalized === 'external' || normalized === 'managed' || normalized === 'docker') {
    return normalized;
  }
  throw new Error(`Invalid CLAUDE_MEM_REDIS_MODE=${value}; expected external, managed, or docker`);
}

function parseRedisPort(value: string): number {
  const port = Number.parseInt(value, 10);
  if (!Number.isInteger(port) || port <= 0 || port > 65535) {
    throw new Error(`Invalid CLAUDE_MEM_REDIS_PORT=${value}; expected a TCP port`);
  }
  return port;
}

function sanitizePrefix(value: string): string {
  return (value.trim() || 'claude_mem').replace(/[^a-zA-Z0-9_-]/g, '_');
}

function connectionFromHost(host: string, port: number): RedisOptions {
  return {
    host,
    port,

View on GitHub (pinned to d8bc9755e7)