{"record":{"id":"1721342ca853731a","repo":"paperclipai/paperclip","slug":"codex-working-directory-must-exist-before-provider","errorCode":null,"errorMessage":"Codex working directory must exist before provider admission","messagePattern":"Codex working directory must exist before provider admission","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/paperclip-runner/src/drivers/codex/codex-boundaries.ts","lineNumber":62,"sourceCode":"  authority: CodexWorkingDirectoryAuthority = \"local_filesystem\",\n): string {\n  if (workingDirectory.trim().length === 0) {\n    throw new Error(\"Codex working directory is required\");\n  }\n  if (authority === \"remote_runner\") {\n    return validateRemoteRunnerWorkingDirectory(workingDirectory, environment);\n  }\n  const requested = resolve(workingDirectory);\n  let resolved: string;\n  try {\n    resolved = realpathSync.native(requested);\n    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    )","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/packages/paperclip-runner/src/drivers/codex/codex-boundaries.ts#L44-L80","documentation":"The boundary validator resolves the requested working directory and calls `statSync` to confirm it exists and is a directory. When the stat fails with ENOENT, the path does not exist on disk, and admission is refused because the Codex session requires a real directory to run in. Note the catch also rethrows other stat errors unchanged.","triggerScenarios":"Calling `validateCodexWorkingDirectory` with a path whose parent exists but target directory was deleted, never created, or is on an unmounted volume (ENOENT).","commonSituations":"Workspace directory removed by cleanup between scheduling and run start; typo in configured path; running in a fresh container where workspace provisioning step was skipped; symlink pointing to a deleted target.","solutions":["Create the working directory before starting the run (fs.mkdir recursive)","Verify the configured path exists on the machine running the driver","Check provisioning/cleanup jobs that may delete workspaces prematurely","If it is a dangling symlink, remove it and create the real directory"],"exampleFix":"// before\nvalidateCodexWorkingDirectory(\"/workspaces/agent-42\");\n// after\nmkdirSync(\"/workspaces/agent-42\", { recursive: true });\nvalidateCodexWorkingDirectory(\"/workspaces/agent-42\");","handlingStrategy":"validation","validationCode":"import { statSync } from \"node:fs\";\ntry {\n  if (!statSync(cwd).isDirectory()) throw new Error(\"not a directory\");\n} catch {\n  mkdirSync(cwd, { recursive: true });\n}","typeGuard":"function directoryExists(p: string): boolean {\n  try { return statSync(p).isDirectory(); } catch { return false; }\n}","tryCatchPattern":"try {\n  validateCodexWorkingDirectory(cwd);\n} catch (err) {\n  if (err.message.includes(\"must exist before provider admission\")) {\n    mkdirSync(cwd, { recursive: true });\n    validateCodexWorkingDirectory(cwd); // retry once after provisioning\n  } else throw err;\n}","preventionTips":["Provision the workspace directory before enqueuing the run","Audit cleanup jobs so they don't delete workspaces of scheduled tasks","Verify path mounts exist inside containers at startup"],"tags":["filesystem","validation","codex"],"backgroundTag":"file-not-found","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"}