{"record":{"id":"b4f709a7a8cbd017","repo":"paperclipai/paperclip","slug":"codex-working-directory-cannot-overlap-host-codex","errorCode":null,"errorMessage":"Codex working directory cannot overlap host CODEX_HOME","messagePattern":"Codex working directory cannot overlap host CODEX_HOME","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/paperclip-runner/src/drivers/codex/codex-boundaries.ts","lineNumber":101,"sourceCode":"      \"Codex working directory cannot overlap sensitive host HOME state\",\n    );\n  }\n  if (\n    hostHome &&\n    pathContains(hostHome, resolved) &&\n    (configuredRoot === undefined || configuredRoot.trim().length === 0)\n  ) {\n    throw new Error(\n      \"Codex working directory inside the host HOME requires an assigned workspace\",\n    );\n  }\n  const codexHome = canonicalConfiguredPath(environment.CODEX_HOME);\n  if (codexHome) {\n    if (\n      pathContains(resolved, codexHome) ||\n      pathContains(codexHome, resolved)\n    ) {\n      throw new Error(\"Codex working directory cannot overlap host CODEX_HOME\");\n    }\n  }\n  if (configuredRoot !== undefined && configuredRoot.trim().length > 0) {\n    const root = canonicalConfiguredPath(configuredRoot)!;\n    const pathFromRoot = relative(root, resolved);\n    if (\n      pathFromRoot === \"..\" ||\n      pathFromRoot.startsWith(`..${sep}`) ||\n      isAbsolute(pathFromRoot)\n    ) {\n      throw new Error(\n        \"Codex working directory is outside the assigned workspace\",\n      );\n    }\n  }\n  return resolved;\n}\n","sourceCodeStart":83,"sourceCodeEnd":119,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/packages/paperclip-runner/src/drivers/codex/codex-boundaries.ts#L83-L119","documentation":"The driver keeps its own state under CODEX_HOME (the Codex CLI's config/session home). If the agent working directory overlaps CODEX_HOME in either direction (working dir contains CODEX_HOME, or is inside it), the session could read or mutate provider state, so the overlap is rejected in both directions.","triggerScenarios":"Setting the working directory to $CODEX_HOME or a parent of it (e.g. HOME when CODEX_HOME=$HOME/.codex, though HOME ancestry is caught earlier), or into ~/.codex itself; or setting CODEX_HOME to a path inside the workspace.","commonSituations":"Developers pointing the workspace at ~/.codex to inspect Codex state; custom CODEX_HOME values that collide with the assigned workspace path; inherited environment where CODEX_HOME was repointed.","solutions":["Change the working directory so it neither contains nor sits inside CODEX_HOME","Move CODEX_HOME to a location disjoint from all workspace roots (e.g. /var/lib/codex)","Unset the stray CODEX_HOME override if it was unintentional"],"exampleFix":"// before\nCODEX_HOME=/workspaces/agent-42/.codex workingDirectory=/workspaces/agent-42\n// after\nCODEX_HOME=/var/lib/codex workingDirectory=/workspaces/agent-42","handlingStrategy":"validation","validationCode":"const codexHome = process.env.CODEX_HOME;\nif (codexHome && (contains(resolve(cwd), resolve(codexHome)) || contains(resolve(codexHome), resolve(cwd)))) {\n  throw new Error(\"workspace and CODEX_HOME must be disjoint\");\n}","typeGuard":"function disjointFromCodexHome(cwd: string, env: NodeJS.ProcessEnv): boolean {\n  const ch = env.CODEX_HOME;\n  return !ch || !(contains(resolve(cwd), resolve(ch)) || contains(resolve(ch), resolve(cwd)));\n}","tryCatchPattern":"try {\n  validateCodexWorkingDirectory(cwd);\n} catch (err) {\n  if (err.message.includes(\"cannot overlap host CODEX_HOME\")) {\n    throw new ConfigError(`relocate CODEX_HOME or pick a different workspace than ${cwd}`);\n  }\n  throw err;\n}","preventionTips":["Place CODEX_HOME outside all workspace roots (e.g. /var/lib/codex)","Document CODEX_HOME expectations for local dev setups","Include CODEX_HOME overlap checks in preflight scripts"],"tags":["security","filesystem","env-var"],"backgroundTag":"path-traversal-blocked","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"}