paperclipai/paperclip · error
Sandbox path alias target "${aliasTarget}" does not exist.
Error message
Sandbox path alias target "${aliasTarget}" does not exist. What it means
Thrown in the pathAliases loop after the workspace-containment check when pathExists(aliasTarget) returns false. The alias passed validation but its host-side source does not exist; bwrap would fail to bind it, so the library surfaces the missing file with the offending path in the message.
Source
Thrown at packages/adapter-utils/src/local-process-sandbox.ts:423
for (const systemPath of SYSTEM_READ_PATHS) await mount(systemPath, "ro");
for (const executablePath of await executableReadPaths(input.executable)) await mount(executablePath, "ro");
if (networkScope === "allowlist") {
for (const nodePath of await executableReadPaths(process.execPath)) await mount(nodePath, "ro");
}
for (const managedPath of input.options.managedPaths ?? []) await mount(managedPath.path, managedPath.access);
for (const extraPath of input.options.extraPaths ?? []) await mount(extraPath.path, extraPath.access);
await mount(workspaceDir, "rw");
for (const [index, alias] of (input.options.pathAliases ?? []).entries()) {
const aliasPath = normalizeAbsolutePath(alias.path, `Sandbox pathAliases[${index}].path`);
const aliasTarget = normalizeAbsolutePath(alias.target, `Sandbox pathAliases[${index}].target`);
const relativeTarget = path.relative(workspaceDir, aliasTarget);
if (relativeTarget.startsWith("..") || path.isAbsolute(relativeTarget)) {
throw new Error(
`Sandbox path alias "${aliasPath}" must target the synchronized workspace "${workspaceDir}".`,
);
}
if (!(await pathExists(aliasTarget))) {
throw new Error(`Sandbox path alias target "${aliasTarget}" does not exist.`);
}
addParentDirectories(args, created, aliasPath);
args.push("--bind", aliasTarget, aliasPath);
created.add(aliasPath);
}
if (networkScope === "allowlist") {
const tempDir = await createNetworkProxyTempDir();
const socketPath = path.join(tempDir, "proxy.sock");
const bridgePath = path.join(tempDir, "bridge.cjs");
await fs.writeFile(bridgePath, await createNetworkProxyBridge(), { mode: 0o500 });
const proxy = await startNetworkAllowlistProxy(
input.options.networkAllowlist ?? [],
input.options.networkTrustedUrls ?? [],
socketPath,
).catch(async (error) => {
await fs.rm(tempDir, { recursive: true, force: true });
throw error;View on GitHub (pinned to 67001ec6eb)
Solutions
- Verify the path with fs.exists() / fs.stat() before calling buildLocalProcessSandboxSpawnTarget and create or fix it if missing.
- Ensure any asset staging step that produces the alias target has awaited completion before sandbox spawn.
- If the target is optional, drop the alias entry when pathExists returns false rather than letting the sandbox builder throw.
- On containers, check that the volume mount backing the target is present (docker inspect, mount(8)) — a missing mount is the usual cause of a path that exists on the host but not in the container.
Example fix
// before
pathAliases: [{ path: "/work/config.json", target: "/srv/work/config.json" }]
// config.json does not yet exist when buildLocalProcessSandboxSpawnTarget runs
// after
await fs.writeFile("/srv/work/config.json", JSON.stringify(config));
pathAliases: [{ path: "/work/config.json", target: "/srv/work/config.json" }] Defensive patterns
Strategy: validation
Validate before calling
async function assertPathAliasTargetsExist(aliases: { path: string; target: string }[]): Promise<void> {
for (const alias of aliases) {
if (!await pathExists(alias.target)) {
throw new Error(`Alias target missing: ${alias.target}`);
}
}
}
await assertPathAliasTargetsExist(input.options.pathAliases ?? []); Try / catch
try {
return await buildLocalProcessSandboxSpawnTarget(input);
} catch (error) {
if (error instanceof Error && error.message.includes("path alias target") && error.message.includes("does not exist")) {
// drop the missing alias and retry, or wait for staging to finish
input.options.pathAliases = (input.options.pathAliases ?? []).filter((a) => pathExistsSync(a.target));
return buildLocalProcessSandboxSpawnTarget(input);
}
throw error;
} Prevention
- Await all asset staging steps before calling the sandbox builder.
- Validate alias targets with fs.stat at config load.
- On containers, verify the volume mount backing each target is present before spawn.
When it happens
Trigger: pathAliases reference a target that has not been created yet, was deleted between config load and sandbox spawn, lives on a mount that is not present in the current container, or is misspelled. The check at local-process-sandbox.ts:422-424 runs after normalizeAbsolutePath and the workspace-containment check, so the path is known to be well-formed and inside the workspace.
Common situations: Asset staging that runs in parallel with sandbox spawn and has not finished writing the alias target; symlink targets whose link exists but whose referent is missing; Docker volume mounts that differ between dev and prod; or simple typos in the configured target path.
Related errors
- Sandbox cwd "${cwd}" must be inside workspaceDir "${workspac
- Writable sandbox path "${normalizedExtraPath}" is outside sy
- Sandbox path alias "${aliasPath}" must target the synchroniz
- filesystemScope must be "workspace".
- Paperclip sandbox proxy socket path is ${pathBytes} bytes, e
AI-assisted analysis of paperclipai/paperclip@67001ec6eb (2026-08-12).
Data as JSON: /api/errors/b7070ea46f32130b.
Report an issue: GitHub.