JuliusBrussee/caveman · error · Error

${name} contains an invalid path character

Error message

${name} contains an invalid path character

What it means

Validation of a Kilo-related environment variable (e.g. KILO_CONFIG_DIR or KILO_CONFIG): its value contains a NUL, carriage return, or newline character. Such bytes cannot appear in a valid filesystem path, so kiloPathFromEnv rejects the variable before it is used to locate config files.

Source

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

  if (!(keyPath[keyPath.length - 1]! in cur)) return true;
  delete cur[keyPath[keyPath.length - 1]!];
  try {
    writeFileSync(path, JSON.stringify(root, null, 2) + "\n");
    return true;
  } catch (e) {
    console.error(`${mark("warn")} cannot write ${path}: ${(e as Error).message}`);
    return false;
  }
}

type KiloConfigLocation = {
  path: string;
  jsonc: boolean;
  source: "KILO_CONFIG_DIR" | "KILO_CONFIG" | "XDG_CONFIG_HOME";
};

function kiloPathFromEnv(value: string, name: string): string {
  if (/[\0\r\n]/.test(value)) throw new Error(`${name} contains an invalid path character`);
  // Kilo passes env paths directly to its loader. Shell-style "~/" expansion
  // does not occur inside an environment value; relative paths resolve from cwd.
  return normalize(isAbsolute(value) ? value : resolve(value));
}

function kiloConfigInDirectory(directory: string, source: KiloConfigLocation["source"]): KiloConfigLocation {
  // Mirror pinned Kilo's native global writer: prefer an existing canonical
  // config in this order, otherwise create kilo.json. JSONC stays read-only here
  // because a JSON stringify would destroy comments.
  const candidates = ["kilo.jsonc", "kilo.json", "opencode.jsonc", "opencode.json"];
  const selected = candidates.map((name) => join(directory, name)).find((path) => existsSync(path))
    ?? join(directory, "kilo.json");
  return { path: selected, jsonc: extname(selected).toLowerCase() === ".jsonc", source };
}

// Kilo 7.5.6's native config writer targets KILO_CONFIG_DIR when present. That
// directory is also loaded after KILO_CONFIG, so it must win for effective MCP
// ownership. Explicit KILO_CONFIG wins only without a custom config directory;

View on GitHub (pinned to 5184b3d11a)

Solutions

  1. Strip stray control characters (NUL, CR, LF) from the named environment variable in your shell or .env source
  2. Check for quoting mistakes like embedded line breaks when exporting the variable
  3. Unset the variable to let Kilo fall back to its default config location
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at packages/cli/src/index.ts:10757 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of JuliusBrussee/caveman@5184b3d11a (2026-09-06). Data as JSON: /api/errors/df768154ab7215d2. Report an issue: GitHub.