paperclipai/paperclip · error
Remote Codex working directory does not match the assigned…
Error message
Remote Codex working directory does not match the assigned workspace
What it means
For remote runners, the controller cannot inspect the provider-owned filesystem, so the facade is pinned to exactly the assigned workspace: the requested working directory must equal the trimmed PAPERCLIP_WORKSPACE_CWD string. This throws when the two differ in any way, meaning the caller attempted to run Codex outside the single assigned remote workspace.
Solutions
- Pass exactly process.env.PAPERCLIP_WORKSPACE_CWD (trimmed) as the remote working directory — the workspace root, not a subpath.
- Regenerate the run config after workspace reassignment so the recorded working directory matches the currently assigned workspace.
- Convert local paths to the remote workspace path before remote validation; never resolve the remote path on the local filesystem.
- Compare with string equality in your own code first (assert(workingDirectory === env.PAPERCLIP_WORKSPACE_CWD?.trim())) to catch drift early.
Example fix
// before const cwd = realpathSync.native(process.env.PAPERCLIP_WORKSPACE_CWD + "/subdir"); validateCodexWorkingDirectory(cwd, process.env, "remote_runner"); // after const cwd = process.env.PAPERCLIP_WORKSPACE_CWD!.trim(); validateCodexWorkingDirectory(cwd, process.env, "remote_runner");
Defensive patterns
Strategy: validation
Validate before calling
const configuredRoot = process.env.PAPERCLIP_WORKSPACE_CWD?.trim();
if (workingDirectory !== configuredRoot) {
throw new Error(`remote cwd must equal assigned workspace: ${workingDirectory} !== ${configuredRoot}`);
} Try / catch
try {
validateCodexWorkingDirectory(workingDirectory, process.env, "remote_runner");
} catch (error) {
if (error instanceof Error && error.message.includes("does not match the assigned workspace")) {
console.error(`cwd=${workingDirectory} workspace=${process.env.PAPERCLIP_WORKSPACE_CWD}`);
}
throw error;
} Prevention
- Treat PAPERCLIP_WORKSPACE_CWD as the single source of truth; build the cwd from it, never from local paths.
- After workspace reassignment, regenerate the run config rather than reusing a stale cwd.
- Do not append subpaths for remote runs — remote Codex always runs at the workspace root.
- Log both strings on mismatch to catch case/slash discrepancies immediately.
When it happens
Trigger: validateCodexWorkingDirectory("/workspaces/other", env, "remote_runner") while env.PAPERCLIP_WORKSPACE_CWD === "/workspaces/issue-42"; also string mismatches like case differences, a trailing slash on one side, or passing the local resolved path instead of the remote workspace path.
Common situations: A controller reusing a local filesystem path (e.g. C:\repo or /home/dev/repo) against a remote runner; a task attempting to cd into a subdirectory of the workspace instead of the workspace root; stale run config referencing a previous workspace after reassignment; locale/case normalization discrepancies on case-insensitive providers.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Assigned remote workspace must be a normalized absolute path
- Remote Codex working directory requires an assigned…
- ACPX provider identity contains an invalid permission mode
- ACPX provider identity contains invalid lifetime fences
- ACPX provider identity is incomplete
AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10).
Data as JSON: /api/errors/992b473a31fcbbcd.
Report an issue: GitHub.
Appendix: source
Thrown at packages/paperclip-runner/src/drivers/codex/codex-boundaries.ts:154
const configuredRoot = environment.PAPERCLIP_WORKSPACE_CWD?.trim();
if (!configuredRoot) {
throw new Error(
"Remote Codex working directory requires an assigned workspace",
);
}
if (
!posix.isAbsolute(configuredRoot) ||
posix.normalize(configuredRoot) !== configuredRoot
) {
throw new Error(
"Assigned remote workspace must be a normalized absolute path",
);
}
// The controller cannot inspect a provider-owned filesystem. Pin the facade
// to the exact remote workspace while runnerd validates existence, type, and
// canonical identity inside the authoritative filesystem before launch.
if (workingDirectory !== configuredRoot) {
throw new Error(
"Remote Codex working directory does not match the assigned workspace",
);
}
return workingDirectory;
}
function canonicalConfiguredPath(value: string | undefined): string | null {
const configured = value?.trim();
if (!configured) return null;
return canonicalPathWithMissingTail(resolve(configured));
}
function canonicalPathWithMissingTail(path: string): string {
let cursor = path;
const missing: string[] = [];
while (true) {
try {
return resolve(realpathSync.native(cursor), ...missing);View on GitHub (pinned to 01ad858492)