thedotmack/claude-mem · error

Invalid CLAUDE_MEM_REDIS_PORT=${value}; expected a TCP port

Error message

Invalid CLAUDE_MEM_REDIS_PORT=${value}; expected a TCP port

What it means

Thrown by parseRedisPort() when CLAUDE_MEM_REDIS_PORT does not parse to an integer in the range 1..65535. Validation is strict: non-numeric, zero, negative, >65535, or fractional values all fail. Port 0 is explicitly rejected.

Source

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

    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,
    maxRetriesPerRequest: null,
    connectTimeout: 1000,
    lazyConnect: true,
  };
}

View on GitHub (pinned to d768ba3643)

Solutions

  1. Set CLAUDE_MEM_REDIS_PORT to a plain integer between 1 and 65535 (commonly 6379).
  2. Strip any non-numeric suffix (e.g. '/tcp' from a Docker port spec).
  3. If using a redis:// URL instead, prefer CLAUDE_MEM_REDIS_URL (the URL's port is parsed separately).

Example fix

// before: export CLAUDE_MEM_REDIS_PORT=6379/tcp
// after: export CLAUDE_MEM_REDIS_PORT=6379
Defensive patterns

Strategy: validation

Validate before calling

function resolveRedisPort(): number {
  const port = Number.parseInt(process.env.CLAUDE_MEM_REDIS_PORT ?? '', 10);
  if (!Number.isInteger(port) || port <= 0 || port > 65535) {
    throw new Error('CLAUDE_MEM_REDIS_PORT must be an integer in 1..65535');
  }
  return port;
}

Type guard

function isValidPort(v: string): boolean {
  const n = Number.parseInt(v, 10);
  return Number.isInteger(n) && n > 0 && n <= 65535 && String(n) === v.trim();
}

Try / catch

try {
  port = parseRedisPort(getQueueSetting('CLAUDE_MEM_REDIS_PORT'));
} catch (error) {
  console.error((error as Error).message);
  process.exit(1);
}

Prevention

When it happens

Trigger: CLAUDE_MEM_REDIS_PORT is empty, a non-numeric string, 0, negative, >65535, or a float.

Common situations: Operator copies a URL-form port into the bare-port setting. A trailing space or unit (e.g. '6379/tcp'). A typo. The variable is unset where a port is required.

Related errors


AI-assisted analysis of thedotmack/claude-mem@d768ba3643 (2026-08-12). Data as JSON: /api/errors/e425f1c3ef497f3d. Report an issue: GitHub.