{"record":{"id":"a9544a6b619bc816","repo":"paperclipai/paperclip","slug":"codex-working-directory-cannot-contain-the-host-ho","errorCode":null,"errorMessage":"Codex working directory cannot contain the host HOME","messagePattern":"Codex working directory cannot contain the host HOME","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/paperclip-runner/src/drivers/codex/codex-boundaries.ts","lineNumber":74,"sourceCode":"    if (!statSync(resolved).isDirectory()) {\n      throw new Error(\"Codex working directory must be a directory\");\n    }\n  } catch (error) {\n    const code = (error as NodeJS.ErrnoException).code;\n    if (code === \"ENOENT\") {\n      throw new Error(\n        \"Codex working directory must exist before provider admission\",\n      );\n    }\n    throw error;\n  }\n  if (resolved === parse(resolved).root) {\n    throw new Error(\"Codex working directory cannot be a filesystem root\");\n  }\n  const configuredRoot = environment.PAPERCLIP_WORKSPACE_CWD;\n  const hostHome = canonicalConfiguredPath(environment.HOME);\n  if (hostHome && pathContains(resolved, hostHome)) {\n    throw new Error(\"Codex working directory cannot contain the host HOME\");\n  }\n  if (\n    hostHome &&\n    SENSITIVE_HOST_HOME_DIRECTORIES.some((directory) =>\n      pathContains(resolve(hostHome, directory), resolved),\n    )\n  ) {\n    throw new Error(\n      \"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\",","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/packages/paperclip-runner/src/drivers/codex/codex-boundaries.ts#L56-L92","documentation":"To prevent leaking host credentials and config into agent sessions, the validator rejects any working directory that contains the host user's HOME directory (i.e. HOME is inside the working dir). Running the agent above HOME would let it traverse into ~/.ssh, ~/.config, etc.","triggerScenarios":"Setting the working directory to `/home/user`, `/Users/name`, or any ancestor of $HOME (e.g. `/home`, `/` variants that survive earlier checks).","commonSituations":"Configuring a shared host directory as the workspace; reusing a personal machine path as the agent workspace; container setups where HOME is mounted at a shallow path.","solutions":["Use a dedicated workspace directory outside the HOME ancestry (e.g. /workspaces/<id>)","Set PAPERCLIP_WORKSPACE_CWD to an assigned workspace root when HOME must be nearby","Restructure the host layout so agent workspaces are siblings, not ancestors, of HOME"],"exampleFix":"// before\nworkingDirectory: \"/home/alice\"\n// after\nworkingDirectory: \"/workspaces/issue-123\"","handlingStrategy":"validation","validationCode":"import { resolve } from \"node:path\";\nconst home = process.env.HOME;\nfunction contains(parent: string, child: string) {\n  const rel = relative(resolve(parent), resolve(child));\n  return rel === \"\" || (!rel.startsWith(\"..\") && !isAbsolute(rel));\n}\nif (home && contains(cwd, home)) throw new Error(\"workspace must not contain HOME\");","typeGuard":"function workspaceSafeFromHome(cwd: string, home?: string): boolean {\n  if (!home) return true;\n  return !contains(cwd, home);\n}","tryCatchPattern":"try {\n  validateCodexWorkingDirectory(cwd);\n} catch (err) {\n  if (err.message.includes(\"cannot contain the host HOME\")) {\n    throw new ConfigError(`workspace ${cwd} overlaps HOME; use an isolated workspace root`);\n  }\n  throw err;\n}","preventionTips":["Keep agent workspaces in a dedicated root such as /workspaces","Never configure HOME, /home, /Users, or their ancestors as workspace paths","Run the validator in CI against your workspace templates"],"tags":["security","filesystem","sandbox"],"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"}