JuliusBrussee/caveman · error · Error

CODEX_HOME points to

Error message

CODEX_HOME points to ${JSON.stringify(configured)}, but that path does not exist

What it means

The CLI honors a CODEX_HOME environment variable override for the Codex home directory, but deliberately does not fall back to a default when the override is set and invalid — falling back silently could route to another account's home. If statSync on the configured path fails with ENOENT, it throws naming the exact configured value.

Solutions

  1. Create the directory: mkdir -p "$CODEX_HOME"
  2. Unset CODEX_HOME (or fix the typo) so the CLI uses the default Codex home
  3. Point CODEX_HOME at an existing directory, e.g. export CODEX_HOME=$HOME/.codex
  4. Check for typos and variable expansion failures in the shell profile that sets CODEX_HOME
  5. In containers/CI, ensure the CODEX_HOME volume is mounted/created before the CLI runs

Example fix

// before
export CODEX_HOME=$HOME/.codexx   # does not exist
// after
export CODEX_HOME=$HOME/.codex    # or: mkdir -p "$CODEX_HOME"
Defensive patterns

Strategy: validation

Validate before calling

import { existsSync, statSync } from 'fs';
const home = process.env.CODEX_HOME;
if (home && (!existsSync(home) || !statSync(home).isDirectory())) {
  throw new Error(`CODEX_HOME=${home} is missing or not a directory`);
}

Try / catch

try {
  cli.codexCommand(args);
} catch (err) {
  if ((err as Error).message.includes('but that path does not exist')) {
    const p = JSON.parse((err as Error).message.match(/CODEX_HOME points to (\".*?\")/)?.[1] ?? '"?"');
    console.error(`Create ${p} (mkdir -p) or unset/fix CODEX_HOME.`);
  } else throw err;
}

Prevention

When it happens

Trigger: CODEX_HOME is set to a path that does not exist when the CLI resolves the Codex home: statSync(configured) throws with code ENOENT — a typo'd path, a deleted/moved directory, or a path that was never created (e.g. ~/codex-home vs ~/.codex).

Common situations: CODEX_HOME pointing at a removed dotfile directory after cleaning ~/.codex; a docker/CI container where the volume mount for CODEX_HOME was never created; switching machines where the old home path doesn't exist; typos like CODEX_HOME=$HOME/.codexx.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20). Data as JSON: /api/errors/3f1ffac3e68e9161. Report an issue: GitHub.

Appendix: source

Thrown at packages/cli/src/index.ts:6198

function agentUserPath(agent: string, path: string): string {
  const prefix = agent === "claude" ? "~/.claude/" : agent === "codex" ? "~/.codex/" : undefined;
  if (!prefix || !path.startsWith(prefix)) return path;
  const root = agent === "claude" ? claudeConfigDir() : codexHomeDir();
  return join(root, path.slice(prefix.length));
}

export function codexHomeDir(env: NodeJS.ProcessEnv = process.env): string {
  const configured = env.CODEX_HOME;
  if (!configured) return join(homedir(), ".codex");
  // Match Codex's own home resolver: a nonempty override may be relative, but
  // must already be a directory and is canonicalized before use. Never fall
  // back to another account's default home when the override is invalid.
  let metadata: ReturnType<typeof statSync>;
  try {
    metadata = statSync(configured);
  } catch (error) {
    if ((error as NodeJS.ErrnoException).code === "ENOENT") {
      throw new Error(`CODEX_HOME points to ${JSON.stringify(configured)}, but that path does not exist`);
    }
    throw new Error(`failed to read CODEX_HOME ${JSON.stringify(configured)}: ${(error as Error).message}`);
  }
  if (!metadata.isDirectory()) {
    throw new Error(`CODEX_HOME points to ${JSON.stringify(configured)}, but that path is not a directory`);
  }
  try {
    return realpathSync(configured);
  } catch (error) {
    throw new Error(`failed to canonicalize CODEX_HOME ${JSON.stringify(configured)}: ${(error as Error).message}`);
  }
}

function codexAuthPath(): string {
  return join(codexHomeDir(), "auth.json");
}

function nonEmptyString(v: unknown): v is string {

View on GitHub (pinned to 3ee70a1026)