{"record":{"id":"76389d723a614159","repo":"paperclipai/paperclip","slug":"assigned-remote-workspace-must-be-a-normalized-abs","errorCode":null,"errorMessage":"Assigned remote workspace must be a normalized absolute path","messagePattern":"Assigned remote workspace must be a normalized absolute path","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/paperclip-runner/src/drivers/codex/codex-boundaries.ts","lineNumber":146,"sourceCode":"  ) {\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    );\n  }\n  return workingDirectory;\n}\n\nfunction canonicalConfiguredPath(value: string | undefined): string | null {\n  const configured = value?.trim();\n  if (!configured) return null;\n  return canonicalPathWithMissingTail(resolve(configured));","sourceCodeStart":128,"sourceCodeEnd":164,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/packages/paperclip-runner/src/drivers/codex/codex-boundaries.ts#L128-L164","documentation":"The assigned workspace itself (the trimmed PAPERCLIP_WORKSPACE_CWD value) is validated before use: it must be a POSIX absolute path already in normalized form (posix.isAbsolute and posix.normalize(value) === value). This throws when the configured workspace root is relative, contains redundant segments like \"//\", \".\", or \"..\", has a trailing slash, or otherwise differs from its normalized form.","triggerScenarios":"PAPERCLIP_WORKSPACE_CWD set to e.g. \"workspaces/x\" (relative), \"/workspaces/x/\" (trailing slash), \"/workspaces//x\", \"/workspaces/./x\", or \"/workspaces/../x\" while calling validateCodexWorkingDirectory(path, env, \"remote_runner\").","commonSituations":"Operator writing the env var by hand with a trailing slash; CI templating producing double slashes from joined strings; relative paths pasted from documentation; containers where HOME-relative shorthand was used instead of an absolute path.","solutions":["Set PAPERCLIP_WORKSPACE_CWD to a fully normalized absolute path with no trailing slash, e.g. \"/workspaces/issue-42\".","Normalize before assigning: root = posix.normalize(posix.resolve(value)) in the code that sets the variable.","Strip trailing slashes and collapse duplicate separators in whatever pipeline generates the env value.","Verify the exact env value at startup with a fail-fast check before launching runners."],"exampleFix":"// before\nPAPERCLIP_WORKSPACE_CWD=/workspaces/issue-42/\n// after\nPAPERCLIP_WORKSPACE_CWD=/workspaces/issue-42  # absolute, no trailing slash, no // or . or ..","handlingStrategy":"validation","validationCode":"const root = process.env.PAPERCLIP_WORKSPACE_CWD?.trim();\nif (!root || !posix.isAbsolute(root) || posix.normalize(root) !== root) {\n  throw new Error(`PAPERCLIP_WORKSPACE_CWD must be a normalized absolute path, got: ${root}`);\n}","typeGuard":"const isNormalizedAbsolutePath = (p: unknown): p is string =>\n  typeof p === \"string\" && posix.isAbsolute(p) && posix.normalize(p) === p;","tryCatchPattern":null,"preventionTips":["Normalize the value once at the single place that assigns PAPERCLIP_WORKSPACE_CWD (posix.normalize + strip trailing slash).","Never hand-write the path in configs; generate it from resolved components.","Add a config linter/startup assertion for env path hygiene."],"tags":["path-validation","invalid-config-value","codex","env"],"backgroundTag":"invalid-config-value","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"}