{"record":{"id":"fb54352aedad4b16","repo":"paperclipai/paperclip","slug":"remote-codex-working-directory-requires-an-assigne","errorCode":null,"errorMessage":"Remote Codex working directory requires an assigned workspace","messagePattern":"Remote Codex working directory requires an assigned workspace","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/paperclip-runner/src/drivers/codex/codex-boundaries.ts","lineNumber":138,"sourceCode":"function validateRemoteRunnerWorkingDirectory(\n  workingDirectory: string,\n  environment: NodeJS.ProcessEnv,\n): string {\n  if (\n    !posix.isAbsolute(workingDirectory) ||\n    posix.normalize(workingDirectory) !== workingDirectory ||\n    /[\\u0000-\\u001f\\u007f]/u.test(workingDirectory)\n  ) {\n    throw new Error(\n      \"Remote Codex working directory must be a normalized absolute path\",\n    );\n  }\n  if (workingDirectory === posix.parse(workingDirectory).root) {\n    throw new Error(\"Codex working directory cannot be a filesystem root\");\n  }\n  const configuredRoot = environment.PAPERCLIP_WORKSPACE_CWD?.trim();\n  if (!configuredRoot) {\n    throw new Error(\n      \"Remote Codex working directory requires an assigned workspace\",\n    );\n  }\n  if (\n    !posix.isAbsolute(configuredRoot) ||\n    posix.normalize(configuredRoot) !== configuredRoot\n  ) {\n    throw new Error(\n      \"Assigned remote workspace must be a normalized absolute path\",\n    );\n  }\n  // The controller cannot inspect a provider-owned filesystem. Pin the facade\n  // to the exact remote workspace while runnerd validates existence, type, and\n  // canonical identity inside the authoritative filesystem before launch.\n  if (workingDirectory !== configuredRoot) {\n    throw new Error(\n      \"Remote Codex working directory does not match the assigned workspace\",\n    );","sourceCodeStart":120,"sourceCodeEnd":156,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/packages/paperclip-runner/src/drivers/codex/codex-boundaries.ts#L120-L156","documentation":"When validating a remote_runner working directory, the validator requires the PAPERCLIP_WORKSPACE_CWD environment variable to be set and non-empty. The remote facade has no filesystem access, so it can only pin the working directory to an explicitly assigned workspace; without that assignment it refuses to proceed. The throw happens when environment.PAPERCLIP_WORKSPACE_CWD is missing, empty, or whitespace-only.","triggerScenarios":"Calling validateCodexWorkingDirectory(path, env, \"remote_runner\") where env.PAPERCLIP_WORKSPACE_CWD is undefined, \"\", or contains only whitespace (e.g. PAPERCLIP_WORKSPACE_CWD unset in the controller process, or set to \" \" via bad env templating).","commonSituations":"Starting the controller/runner service without the workspace-assignment env var in a remote provider deployment; a deployment pipeline dropping the variable; local dev configs used against a remote runner where the var is only set in production.","solutions":["Export PAPERCLIP_WORKSPACE_CWD to the normalized absolute remote workspace path (e.g. /workspaces/issue-42) in the process calling this validator.","Ensure the code path that spawns/validates the remote runner passes its environment through instead of a stripped process.env.","Provision the remote workspace and record its path before launching Codex; only launch after assignment exists.","Fix templating that renders the variable to an empty string."],"exampleFix":"// before\nspawnRunner({ cwd: workingDirectory }); // env lacks PAPERCLIP_WORKSPACE_CWD\n// after\nprocess.env.PAPERCLIP_WORKSPACE_CWD ??= \"/workspaces/issue-42\";\nspawnRunner({ cwd: validateCodexWorkingDirectory(workingDirectory, process.env, \"remote_runner\") });","handlingStrategy":"validation","validationCode":"const configuredRoot = process.env.PAPERCLIP_WORKSPACE_CWD?.trim();\nif (!configuredRoot) throw new Error(\"PAPERCLIP_WORKSPACE_CWD must be set before remote Codex runs\");","typeGuard":"const hasAssignedWorkspace = (env: NodeJS.ProcessEnv): boolean =>\n  typeof env.PAPERCLIP_WORKSPACE_CWD === \"string\" && env.PAPERCLIP_WORKSPACE_CWD.trim().length > 0;","tryCatchPattern":"try {\n  validateCodexWorkingDirectory(cwd, process.env, \"remote_runner\");\n} catch (error) {\n  if (error instanceof Error && error.message.includes(\"requires an assigned workspace\")) {\n    throw new Error(\"Set PAPERCLIP_WORKSPACE_CWD to the provisioned remote workspace path before launching remote Codex runs\", { cause: error });\n  }\n  throw error;\n}","preventionTips":["Include PAPERCLIP_WORKSPACE_CWD in deployment env templates and startup health checks.","Fail fast at process start when the variable is missing in remote mode.","Provision the workspace and write its path to env/config before any launch call."],"tags":["missing-env-var","codex","remote-runner","config"],"backgroundTag":"missing-env-var","analyzedSha":"01ad8584922b5d85292b1723cae71fa0d9b07a19","analyzedAt":"2026-09-10T03:14:50.855Z","contentChangedAt":"2026-09-10T03:14:50.855Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}