paperclipai/paperclip · error · Error
sync operation path escapes its confinement root
Error message
sync operation ${label} path escapes its confinement root: ${candidate} What it means
Host-side complete-mediation guard for native sandbox sync: the path canonicalizes fine but resolves outside every allowed orchestrator-owned root (sourceRoots/targetRoots), so the sync would touch files the orchestrator does not own and is rejected before provider handoff.
Solutions
- Keep the sync operation path inside its confinement root; remove traversal segments.
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at packages/adapter-utils/src/sandbox-managed-runtime.ts:281 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/db2232eb93b38f3a.
Report an issue: GitHub.
Appendix: source
Thrown at packages/adapter-utils/src/sandbox-managed-runtime.ts:311
.filter(Boolean);
}
/**
* Bounded backoff before each retry of a saturated Git scan: none before the
* first attempt, 1 second before the second, 2 seconds before the third. Three
* total attempts (the first plus these two retries) is a liveness parameter,
* not a security control — the retry only ever fires for the scheduler's
* typed saturation code (see {@link isWorkspaceGitScanSaturatedError}).
*/
const REFERENCED_SOURCE_IGNORE_SCAN_RETRY_DELAYS_MS = [1_000, 2_000] as const;
async function delay(ms: number): Promise<void> {
await new Promise<void>((resolve) => setTimeout(resolve, ms));
}
/**
* True only when `error` carries the workspace Git scan scheduler's typed
* saturation code on its `code` property. Matches the code alone, never
* message text — a message can change wording without changing meaning, and
* matching text would silently stop retrying (or start retrying the wrong
* failure) the moment it did.
*/
function isWorkspaceGitScanSaturatedError(error: unknown): boolean {
return (
typeof error === "object" &&
error !== null &&
"code" in error &&
(error as { code?: unknown }).code === WORKSPACE_GIT_SCAN_SATURATED_CODE
);
}
/**
* Resolve a referenced project's Git-ignored paths ONCE, before any staging
* site runs. Called once per project (see `execute.ts`); the sandbox lane,
* the SSH lane, and the content-signature walk all consume this one result,
* so they can never apply a different exclusion set to the same project.View on GitHub (pinned to 3f1d897a7c)