paperclipai/paperclip · error

post-upload command cwd is not a confined absolute POSIX…

Error message

post-upload command cwd is not a confined absolute POSIX path: ${raw}

What it means

Host-side confinement guard (Security Condition C2) checked before any sandbox handoff: a sync operation's post-upload command `cwd` is either not an absolute POSIX path or contains a '..' segment, so it is rejected fail-closed before a provider ever executes it.

Solutions

  1. Use a confined absolute POSIX path (under the operation's target root) for the post-upload command cwd.
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at packages/adapter-utils/src/command-managed-runtime.ts:187 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of paperclipai/paperclip@3f1d897a7c (2026-08-18). Data as JSON: /api/errors/50c9f1f02424a622. Report an issue: GitHub.

Appendix: source

Thrown at packages/adapter-utils/src/command-managed-runtime.ts:238

  await client.remove(remotePath).catch(() => undefined);
}

/**
 * Host-side confinement guard for a sync operation's post-upload command `cwd`
 * (Security Condition C2). Runs BEFORE any handoff — native delegation OR the
 * generic fallback — so an out-of-root `cwd` is rejected fail-closed before a
 * provider ever sees it. `cwd` (when present) MUST be an absolute POSIX path with
 * no `..` segment, confined to (equal to or under) one of the operation's own
 * file-mapping target paths. Commands with no `cwd` are unconstrained here and
 * default to the runtime's stable command cwd at exec time.
 */
export function assertPostUploadCommandsConfined(operations: readonly SandboxSyncOperation[]): void {
  for (const operation of operations) {
    const commands = operation.postUploadCommands ?? [];
    if (commands.length === 0) continue;
    const targetRoots = operation.files.map((mapping) => path.posix.normalize(mapping.targetPath));
    for (const command of commands) {
      if (command.cwd == null) continue;
      const raw = command.cwd;
      if (!path.posix.isAbsolute(raw) || raw.split("/").includes("..")) {
        throw new Error(`post-upload command cwd is not a confined absolute POSIX path: ${raw}`);
      }
      const normalized = path.posix.normalize(raw);
      const within = targetRoots.some(
        (root) => normalized === root || normalized.startsWith(`${root}/`),
      );
      if (!within) {
        throw new Error(`post-upload command cwd escapes the operation's target root: ${raw}`);
      }
    }
  }
}

export function createCommandManagedRuntimeClient(input: {
  runner: CommandManagedRuntimeRunner;
  commandCwd: string;

View on GitHub (pinned to 3f1d897a7c)