{"record":{"id":"758803bd453b7fec","repo":"paperclipai/paperclip","slug":"codex-startup-trust-requires-absolute-paths","errorCode":"codex_startup_trust_requires_absolute_paths","errorMessage":"codex_startup_trust_requires_absolute_paths","messagePattern":"codex_startup_trust_requires_absolute_paths","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/paperclip-runner/src/drivers/codex/codex-startup-trust.ts","lineNumber":58,"sourceCode":"  // Inline project tables are closed to appended table headers. Insert only\n  // when reparsing proves this is the intended object, not a brace in text.\n  const fields = ['trust_level = \"trusted\"', `${JSON.stringify(root)} = { trust_level = \"trusted\" }`];\n  for (const match of source.matchAll(/\\{/g)) {\n    const end = match.index! + 1;\n    for (const field of fields) {\n      for (const separator of [', ', '']) {\n        const candidate = source.slice(0, end) + field + separator + source.slice(end);\n        if (matches(candidate)) return candidate;\n      }\n    }\n  }\n  throw new Error(\"codex_startup_trust_cannot_preserve_configuration\");\n}\n\n/** Run on the execution host, before the provider process loads project config. */\nexport function trustCodexStartupRoot(codexHome: string, cwd: string): void {\n  if (!isAbsolute(codexHome) || !isAbsolute(cwd))\n    throw new Error(\"codex_startup_trust_requires_absolute_paths\");\n  const startup = realpathSync(cwd);\n  let root = startup;\n  try {\n    const top = execFileSync(\n      \"git\",\n      [\"-C\", startup, \"rev-parse\", \"--show-toplevel\"],\n      { encoding: \"utf8\", timeout: 5000, stdio: [\"ignore\", \"pipe\", \"ignore\"] },\n    ).trim();\n    const common = execFileSync(\n      \"git\",\n      [\n        \"-C\",\n        startup,\n        \"rev-parse\",\n        \"--path-format=absolute\",\n        \"--git-common-dir\",\n      ],\n      { encoding: \"utf8\", timeout: 5000, stdio: [\"ignore\", \"pipe\", \"ignore\"] },","sourceCodeStart":40,"sourceCodeEnd":76,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/packages/paperclip-runner/src/drivers/codex/codex-startup-trust.ts#L40-L76","documentation":"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.","triggerScenarios":"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).","commonSituations":"Config files storing relative workspace paths, shell scripts passing unexpanded '~', drivers constructing cwd from user input without path.resolve.","solutions":["Resolve both inputs with path.resolve() (and expand '~' via os.homedir()) before calling trustCodexStartupRoot.","Check isAbsolute(codexHome) && isAbsolute(cwd) at the call site and fail fast with a clear message.","If cwd comes from a config, store absolute paths at write time rather than normalizing at call time."],"exampleFix":"// before\ntrustCodexStartupRoot('~/.codex', 'repo');\n// after\ntrustCodexStartupRoot(\n  path.join(os.homedir(), '.codex'),\n  path.resolve('repo'),\n);","handlingStrategy":"validation","validationCode":"import { isAbsolute } from 'node:path';\nif (!isAbsolute(codexHome) || !isAbsolute(cwd)) throw new Error(`codex paths must be absolute: home=${codexHome} cwd=${cwd}`);","typeGuard":"const isAbsPair = (h: string, c: string): boolean => isAbsolute(h) && isAbsolute(c);","tryCatchPattern":"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; }","preventionTips":["Always derive codexHome from path.join(os.homedir(), '.codex')","Always pass path.resolve()'d workspace directories","Store absolute paths in configs; never store '~'-prefixed or relative paths","Add a startup assertion that logs both paths before the driver runs"],"tags":["codex","paths","validation","config"],"backgroundTag":"invalid-argument-format","analyzedSha":"01ad8584922b5d85292b1723cae71fa0d9b07a19","analyzedAt":"2026-09-10T03:14:50.855Z","contentChangedAt":"2026-09-10T03:14:50.855Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}