paperclipai/paperclip · error · Error

sync operation path is not a confined absolute path

Error message

sync operation ${label} path is not a confined absolute path: ${candidate}

What it means

Host-side complete-mediation guard for native sandbox sync: a sync operation's source or target path (labelled in the message) is not a confined absolute POSIX path — it is relative, or contains '..' traversal — so it is rejected fail-closed before the operation crosses the host-sandbox trust boundary.

Solutions

  1. Use a confined absolute path inside the operation's root for sync operation ${label}.
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at packages/adapter-utils/src/sandbox-managed-runtime.ts:273 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/d84eb513dbeb1d79. Report an issue: GitHub.

Appendix: source

Thrown at packages/adapter-utils/src/sandbox-managed-runtime.ts:303

function reRelativizeIgnoredPathsToLocalPath(input: { ignoredPaths: string[]; offset: string }): string[] {
  if (input.offset === "") {
    return [...input.ignoredPaths];
  }
  const prefix = `${input.offset}/`;
  return input.ignoredPaths
    .filter((entry) => entry.startsWith(prefix))
    .map((entry) => entry.slice(prefix.length))
    .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

View on GitHub (pinned to 3f1d897a7c)