paperclipai/paperclip · error

Codex working directory must exist before provider admission

Error message

Codex working directory must exist before provider admission

What it means

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.

Source

Thrown at packages/paperclip-runner/src/drivers/codex/codex-boundaries.ts:62

  authority: CodexWorkingDirectoryAuthority = "local_filesystem",
): string {
  if (workingDirectory.trim().length === 0) {
    throw new Error("Codex working directory is required");
  }
  if (authority === "remote_runner") {
    return validateRemoteRunnerWorkingDirectory(workingDirectory, environment);
  }
  const requested = resolve(workingDirectory);
  let resolved: string;
  try {
    resolved = realpathSync.native(requested);
    if (!statSync(resolved).isDirectory()) {
      throw new Error("Codex working directory must be a directory");
    }
  } catch (error) {
    const code = (error as NodeJS.ErrnoException).code;
    if (code === "ENOENT") {
      throw new Error(
        "Codex working directory must exist before provider admission",
      );
    }
    throw error;
  }
  if (resolved === parse(resolved).root) {
    throw new Error("Codex working directory cannot be a filesystem root");
  }
  const configuredRoot = environment.PAPERCLIP_WORKSPACE_CWD;
  const hostHome = canonicalConfiguredPath(environment.HOME);
  if (hostHome && pathContains(resolved, hostHome)) {
    throw new Error("Codex working directory cannot contain the host HOME");
  }
  if (
    hostHome &&
    SENSITIVE_HOST_HOME_DIRECTORIES.some((directory) =>
      pathContains(resolve(hostHome, directory), resolved),
    )

View on GitHub (pinned to 01ad858492)

Solutions

  1. Create the working directory before starting the run (fs.mkdir recursive)
  2. Verify the configured path exists on the machine running the driver
  3. Check provisioning/cleanup jobs that may delete workspaces prematurely
  4. If it is a dangling symlink, remove it and create the real directory

Example fix

// before
validateCodexWorkingDirectory("/workspaces/agent-42");
// after
mkdirSync("/workspaces/agent-42", { recursive: true });
validateCodexWorkingDirectory("/workspaces/agent-42");
Defensive patterns

Strategy: validation

Validate before calling

import { statSync } from "node:fs";
try {
  if (!statSync(cwd).isDirectory()) throw new Error("not a directory");
} catch {
  mkdirSync(cwd, { recursive: true });
}

Type guard

function directoryExists(p: string): boolean {
  try { return statSync(p).isDirectory(); } catch { return false; }
}

Try / catch

try {
  validateCodexWorkingDirectory(cwd);
} catch (err) {
  if (err.message.includes("must exist before provider admission")) {
    mkdirSync(cwd, { recursive: true });
    validateCodexWorkingDirectory(cwd); // retry once after provisioning
  } else throw err;
}

Prevention

When it happens

Trigger: Calling `validateCodexWorkingDirectory` with a path whose parent exists but target directory was deleted, never created, or is on an unmounted volume (ENOENT).

Common situations: 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.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10). Data as JSON: /api/errors/1721342ca853731a. Report an issue: GitHub.