thedotmack/claude-mem · error · HostObserverUnavailableError

CLAUDE_MEM_HOST_OBSERVER_PORT=${configuredRaw} is not a vali

Error message

CLAUDE_MEM_HOST_OBSERVER_PORT=${configuredRaw} is not a valid port. Set it to the port your OpenAI-compatible observer already listens on.

What it means

Host observer mode reuses an OpenAI-compatible HTTP server already running on your machine; you point it there via CLAUDE_MEM_HOST_OBSERVER_PORT. Before probing, resolveHostObserverPort parses the variable with parsePort, and any value that is not a plain valid port number (1-65535) makes the install fail fast with this HostObserverUnavailableError so a typo'd URL, protocol prefix, or empty string never gets probed.

Source

Thrown at src/npx-cli/cmem-memory-credentials.ts:237

    };
  }

  return null;
}

/** Atomically move staged/current credentials into the active provider slot. */

export function resolveHostObserverPort(
  workerPort: string | number | undefined,
  env: NodeJS.ProcessEnv = process.env,
  probe: HostObserverPortProbe = probeHostObserverPortSync,
): string {
  const worker = parsePort(typeof workerPort === 'number' ? workerPort : nonEmptyString(workerPort));
  const configuredRaw = nonEmptyString(env.CLAUDE_MEM_HOST_OBSERVER_PORT);
  if (configuredRaw) {
    const configured = parsePort(configuredRaw);
    if (configured == null) {
      throw new HostObserverUnavailableError(
        `CLAUDE_MEM_HOST_OBSERVER_PORT=${configuredRaw} is not a valid port. Set it to the port your OpenAI-compatible observer already listens on.`,
      );
    }
    if (worker != null && configured === worker) {
      throw new HostObserverUnavailableError(
        `CLAUDE_MEM_HOST_OBSERVER_PORT=${configured} is the claude-mem worker port. Point it at your OpenAI-compatible observer instead.`,
      );
    }
    const status = probe(configured);
    if (status === 'observer') return String(configured);
    if (status === 'occupied') {
      throw new HostObserverUnavailableError(
        `CLAUDE_MEM_HOST_OBSERVER_PORT=${configured} is occupied by a process that is not an OpenAI-compatible observer. Stop that process or point CLAUDE_MEM_HOST_OBSERVER_PORT at your observer.`,
      );
    }
    throw new HostObserverUnavailableError(
      `CLAUDE_MEM_HOST_OBSERVER_PORT=${configured} has nothing listening. Start your OpenAI-compatible observer on that port, then rerun with --provider host.`,
    );

View on GitHub (pinned to 8bc631a71a)

Solutions

  1. Set CLAUDE_MEM_HOST_OBSERVER_PORT to the bare integer port your observer listens on, e.g. export CLAUDE_MEM_HOST_OBSERVER_PORT=4141
  2. Unset the variable entirely (unset CLAUDE_MEM_HOST_OBSERVER_PORT) to let claude-mem auto-probe default ports 37777/37778
  3. Verify the value is a decimal number in 1-65535 with no scheme, slashes, or spaces, then rerun the install with --provider host

Example fix

// before
export CLAUDE_MEM_HOST_OBSERVER_PORT=http://127.0.0.1:4141
// after
export CLAUDE_MEM_HOST_OBSERVER_PORT=4141
Defensive patterns

Strategy: validation

Validate before calling

const raw = process.env.CLAUDE_MEM_HOST_OBSERVER_PORT;
if (raw) {
  const port = Number(raw);
  if (!Number.isInteger(port) || port < 1 || port > 65535) {
    throw new Error(`CLAUDE_MEM_HOST_OBSERVER_PORT=${raw} is not a valid port (1-65535)`);
  }
}

Type guard

const isValidPort = (v: unknown): v is number =>
  typeof v === 'number' && Number.isInteger(v) && v >= 1 && v <= 65535;

Try / catch

try {
  const port = resolveHostObserverPort(workerPort, env);
} catch (e) {
  if (e instanceof HostObserverUnavailableError && e.message.includes('is not a valid port')) {
    delete process.env.CLAUDE_MEM_HOST_OBSERVER_PORT; // fall back to auto-discovery
  } else throw e;
}

Prevention

When it happens

Trigger: Running `npx claude-mem install --provider host` (or any code path calling resolveHostObserverPort / buildHostObserverSettings) with CLAUDE_MEM_HOST_OBSERVER_PORT set to something parsePort rejects — e.g. 'http://127.0.0.1:4141', '4141/', '0', '99999', 'abc', or whitespace.

Common situations: Copy-pasting a full base URL instead of the bare port from an observer's docs; setting the variable in shell rc with quotes/newline; typos like '414l'; setting it to 0 or a 6-digit out-of-range port.

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@8bc631a71a (2026-09-09). Data as JSON: /api/errors/8355edf293275e05. Report an issue: GitHub.