paperclipai/paperclip · error

codex_startup_trust_requires_absolute_paths

codex_startup_trust_requires_absolute_paths

Error message

codex_startup_trust_requires_absolute_paths

What it means

trustCodexStartupRoot prepares the Codex startup trust entry for a project root before the provider process loads project config. It throws this error when either codexHome or cwd is not an absolute filesystem path, because Codex config.toml keys projects by absolute real paths and relative inputs would produce a wrong trust key.

Source

Thrown at packages/paperclip-runner/src/drivers/codex/codex-startup-trust.ts:58

  // Inline project tables are closed to appended table headers. Insert only
  // when reparsing proves this is the intended object, not a brace in text.
  const fields = ['trust_level = "trusted"', `${JSON.stringify(root)} = { trust_level = "trusted" }`];
  for (const match of source.matchAll(/\{/g)) {
    const end = match.index! + 1;
    for (const field of fields) {
      for (const separator of [', ', '']) {
        const candidate = source.slice(0, end) + field + separator + source.slice(end);
        if (matches(candidate)) return candidate;
      }
    }
  }
  throw new Error("codex_startup_trust_cannot_preserve_configuration");
}

/** Run on the execution host, before the provider process loads project config. */
export function trustCodexStartupRoot(codexHome: string, cwd: string): void {
  if (!isAbsolute(codexHome) || !isAbsolute(cwd))
    throw new Error("codex_startup_trust_requires_absolute_paths");
  const startup = realpathSync(cwd);
  let root = startup;
  try {
    const top = execFileSync(
      "git",
      ["-C", startup, "rev-parse", "--show-toplevel"],
      { encoding: "utf8", timeout: 5000, stdio: ["ignore", "pipe", "ignore"] },
    ).trim();
    const common = execFileSync(
      "git",
      [
        "-C",
        startup,
        "rev-parse",
        "--path-format=absolute",
        "--git-common-dir",
      ],
      { encoding: "utf8", timeout: 5000, stdio: ["ignore", "pipe", "ignore"] },

View on GitHub (pinned to 01ad858492)

Solutions

  1. Resolve both inputs with path.resolve() (and expand '~' via os.homedir()) before calling trustCodexStartupRoot.
  2. Check isAbsolute(codexHome) && isAbsolute(cwd) at the call site and fail fast with a clear message.
  3. If cwd comes from a config, store absolute paths at write time rather than normalizing at call time.

Example fix

// before
trustCodexStartupRoot('~/.codex', 'repo');
// after
trustCodexStartupRoot(
  path.join(os.homedir(), '.codex'),
  path.resolve('repo'),
);
Defensive patterns

Strategy: validation

Validate before calling

import { isAbsolute } from 'node:path';
if (!isAbsolute(codexHome) || !isAbsolute(cwd)) throw new Error(`codex paths must be absolute: home=${codexHome} cwd=${cwd}`);

Type guard

const isAbsPair = (h: string, c: string): boolean => isAbsolute(h) && isAbsolute(c);

Try / catch

try { trustCodexStartupRoot(codexHome, cwd); } catch (e) { if ((e as Error).message === 'codex_startup_trust_requires_absolute_paths') { trustCodexStartupRoot(path.resolve(expandHome(codexHome)), path.resolve(cwd)); } else throw e; }

Prevention

When it happens

Trigger: Calling trustCodexStartupRoot with a relative codexHome (e.g. '~/.codex' unexpanded or '.codex') or a relative cwd (e.g. '.', 'repo/', or a path from process.argv without resolution).

Common situations: Config files storing relative workspace paths, shell scripts passing unexpanded '~', drivers constructing cwd from user input without path.resolve.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10). Data as JSON: /api/errors/758803bd453b7fec. Report an issue: GitHub.