paperclipai/paperclip · error

codex_startup_trust_invalid_projects

codex_startup_trust_invalid_projects

Error message

codex_startup_trust_invalid_projects

What it means

Before writing trust_level, the function parses the existing config.toml into a structured config and validates that the projects section is a plain object. It throws this error when config.projects exists but is an array, a Date, or otherwise not a normal object, because it cannot safely merge trust entries into that shape.

Source

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

    for (let ancestor = startup; ; ancestor = dirname(ancestor)) {
      if (existsSync(join(ancestor, ".git")))
        throw new Error("codex_startup_trust_git_resolution_failed", {
          cause: error,
        });
      if (dirname(ancestor) === ancestor) break;
    }
  }
  mkdirSync(codexHome, { recursive: true, mode: 0o700 });
  const path = join(codexHome, "config.toml");
  const source = existsSync(path) ? readFileSync(path, "utf8") : "";
  const config = parse(source);
  const projects = config.projects ?? {};
  if (
    typeof projects !== "object" ||
    Array.isArray(projects) ||
    projects instanceof Date
  )
    throw new Error("codex_startup_trust_invalid_projects");
  const project = projects[root] ?? {};
  if (
    typeof project !== "object" ||
    Array.isArray(project) ||
    project instanceof Date
  )
    throw new Error("codex_startup_trust_invalid_project");
  config.projects = {
    ...projects,
    [root]: { ...project, trust_level: "trusted" },
  };
  const updated = editTrust(source, root, config);
  if (updated === source) return;
  const temporary = resolve(codexHome, `config.toml.${randomUUID()}.tmp`);
  try {
    writeFileSync(temporary, updated, { mode: 0o600, flag: "wx" });
    renameSync(temporary, path);
  } finally {

View on GitHub (pinned to 01ad858492)

Solutions

  1. Open codexHome/config.toml and fix the projects section to be a proper TOML table keyed by absolute paths.
  2. Back up and remove/repair the malformed config.toml so a fresh one can be written.
  3. Validate the parsed config with a schema check before running the driver to catch the corruption early.
  4. Upgrade/align the Codex CLI version so its config format matches what the parser expects.

Example fix

// before (config.toml)
projects = ["/repo"]
// after (config.toml)
[projects."/repo"]
trust_level = "trusted"
Defensive patterns

Strategy: validation

Validate before calling

function projectsIsPlainObject(config: unknown): boolean {
  const p = (config as { projects?: unknown })?.projects;
  return p === undefined || (typeof p === 'object' && p !== null && !Array.isArray(p) && !(p instanceof Date));
}

Type guard

const isPlainRecord = (v: unknown): v is Record<string, unknown> => typeof v === 'object' && v !== null && !Array.isArray(v) && !(v instanceof Date);

Try / catch

try { trustCodexStartupRoot(codexHome, cwd); } catch (e) { if ((e as Error).message === 'codex_startup_trust_invalid_projects') { backupConfigToml(); resetProjectsSection(); trustCodexStartupRoot(codexHome, cwd); } else throw e; }

Prevention

When it happens

Trigger: A hand-edited or corrupted ~/.codex/config.toml where [projects] resolves to a non-object value (e.g. projects = [] or a TOML table array of projects), or a parser returning Date-wrapped values.

Common situations: Users pasting invalid TOML, older Codex config formats using an array of project entries, automated writers corrupting the file, shared dotfiles synced between machines.

Related errors


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