JuliusBrussee/caveman · error · Error

KILO_DB contains an invalid path character

Error message

KILO_DB contains an invalid path character

What it means

Thrown while resolving the database path when the KILO_DB environment variable contains NUL, carriage return, or newline characters. The library rejects these because they make filesystem paths ambiguous or dangerous and cannot appear in a valid path. It ensures the SQLite database location derived from KILO_DB is a clean, usable path.

Source

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

  try {
    preferenceFiles.unshift(join("/Library/Managed Preferences", userInfo().username, "ai.opencode.managed.plist"));
  } catch {
    // System-level preference remains covered; an unreadable username is itself
    // unusual, but no user path can be resolved safely enough to claim absence.
    return true;
  }
  return preferenceFiles.some((path) => existsSync(path));
}

function kiloDatabasePath(): string | null {
  const rawDataRoot = process.env.XDG_DATA_HOME || join(homedir(), ".local", "share");
  const cleanedDataRoot = rawDataRoot.replace(/[\r\n]+/g, "");
  if (!cleanedDataRoot) throw new Error("Kilo data root resolves to an empty path");
  const dataRoot = normalize(isAbsolute(cleanedDataRoot) ? cleanedDataRoot : resolve(cleanedDataRoot));
  const configured = process.env.KILO_DB;
  if (configured === ":memory:") return null;
  if (configured) {
    if (/[\0\r\n]/.test(configured)) throw new Error("KILO_DB contains an invalid path character");
    return normalize(isAbsolute(configured) ? configured : join(dataRoot, "kilo", configured));
  }
  return join(dataRoot, "kilo", "kilo.db");
}

function kiloActiveOrganizationState(): "none" | "active" | "unknown" {
  let path: string | null;
  try {
    path = kiloDatabasePath();
    if (path === null) return "none";
    const stat = statSync(path);
    if (!stat.isFile()) return "unknown";
  } catch (error) {
    if ((error as NodeJS.ErrnoException).code === "ENOENT") return "none";
    return "unknown";
  }
  const script = [
    'const { DatabaseSync } = require("node:sqlite");',

View on GitHub (pinned to 5184b3d11a)

Solutions

  1. Remove newline/CR/NUL characters from the KILO_DB value: export KILO_DB="$(printf '%s' "$KILO_DB" | tr -d '\r\n')".
  2. Verify the env var with node -e 'console.log(JSON.stringify(process.env.KILO_DB))' to reveal hidden control characters.
  3. Unset KILO_DB entirely to fall back to the default <dataRoot>/kilo/kilo.db path.
  4. Fix the source (CI secret, .env file, shell profile) that injects the control character instead of patching it at use time.

Example fix

// before
export KILO_DB="db/kilo.db
"
// after
export KILO_DB="db/kilo.db"
Defensive patterns

Strategy: validation

Validate before calling

const kb = process.env.KILO_DB;
if (kb && /[\0\r\n]/.test(kb)) throw new Error("KILO_DB contains an invalid path character");

Prevention

When it happens

Trigger: Setting process.env.KILO_DB to a value matching /[\0\r\n]/, e.g. a value copied from a Windows file with CRLF line endings, or a shell variable that embedded a literal newline in the path.

Common situations: Exporting KILO_DB from a script or CI secret that has trailing newline/CRLF; constructing the env var by concatenating strings that included a line break; pasting a Windows path with embedded CR characters into a .env file.

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 JuliusBrussee/caveman@5184b3d11a (2026-09-06). Data as JSON: /api/errors/f4131caafd3e130e. Report an issue: GitHub.