paperclipai/paperclip · error
additional source localPath is not an absolute path: ${local
Error message
additional source localPath is not an absolute path: ${localPath} What it means
Thrown while iterating input.additionalSources when a source's localPath is not a POSIX-absolute path. Additional (referenced) projects ride one confined directory sync each; because the confinement logic and the sync transport require an absolute source, a relative path is rejected before any transfer is attempted. The error is per-source and caught by the surrounding try block so other projects continue.
Source
Thrown at packages/adapter-utils/src/sandbox-managed-runtime.ts:1011
progressBytes: assetTarSize,
});
}
// Stage each referenced (additional) project as a plain, read-only tree in
// its OWN isolated remote directory (`project-<projectId>`). An additional
// project rides one confined `syncIn` directory mapping — a native directory
// transfer, or the base64-tar fallback — with source and target confined to
// their own roots. No workspace, git-history, or `.paperclip-runtime`
// semantics apply; those stay anchor-only. Per-project failure isolation: one
// project's confinement or sync failure logs a warning and is skipped, and
// the run plus the other projects continue. Only a project that stages
// successfully appears in `additionalSourceDirs`.
for (const source of input.additionalSources ?? []) {
const { localPath, projectId } = source;
const label = `project-${projectId}`;
try {
if (!path.posix.isAbsolute(localPath)) {
throw new Error(`additional source localPath is not an absolute path: ${localPath}`);
}
if (
projectId.length === 0 ||
projectId.includes("/") ||
projectId.includes("\\") ||
projectId.includes("..")
) {
throw new Error(`additional source projectId is not a simple path segment: ${projectId}`);
}
const remoteProjectDir = path.posix.join(runtimeRootDir, label);
await emitRuntimeStatus(input.onRuntimeProgress, "config_sync", "Syncing referenced project to sandbox");
await stageConfinedSyncIn({
files: [{
sourcePath: localPath,
targetPath: remoteProjectDir,
kind: "directory",
exclude: additionalSourceExclude,
access: "ro",View on GitHub (pinned to 67001ec6eb)
Solutions
- Resolve additionalSource.localPath with path.resolve() (or path.posix.resolve for remote-style) before passing it in.
- Validate localPath at the API boundary that collects additional sources.
- Confirm the source object came from a resolver that emits absolute paths, not a raw user string.
- Check the per-project failure is logged as a warning (the surrounding catch skips that project) and fix the offending entry.
Example fix
// before
additionalSources: [{ localPath: 'libs/shared', projectId: 'shared' }]
// after
additionalSources: [{ localPath: path.resolve(workspaceRoot, 'libs/shared'), projectId: 'shared' }] Defensive patterns
Strategy: validation
Validate before calling
for (const s of additionalSources ?? []) {
if (!path.posix.isAbsolute(s.localPath)) {
throw new Error(`additionalSource localPath must be absolute: ${s.localPath}`);
}
} Type guard
function isAbsoluteLocalPath(p: string): boolean {
return typeof p === 'string' && path.posix.isAbsolute(p);
} Prevention
- Resolve additional-source paths at the collection boundary with path.resolve.
- Treat the additionalSources field as requiring absolute paths in its type.
- Log skipped projects (the surrounding catch already warns) to catch regressions.
When it happens
Trigger: prepareSandboxManagedRuntime called with additionalSources containing an entry whose localPath lacks a leading slash (e.g. 'libs/shared' or './repo'). path.posix.isAbsolute returns false and this throws inside the per-project try.
Common situations: Caller passes a workspace-relative reference path instead of resolving it; a config field that should hold an absolute repo root was populated with a relative glob; cross-platform path handling produced a driveless path on the orchestrator.
Related errors
- additional source projectId is not a simple path segment: ${
- Command "${command}" is not installed or not on PATH in the
- networkAllowlist[${index}] must not be empty.
- networkAllowlist[${index}] must be a hostname, hostname:port
- networkAllowlist[${index}] must use an exact hostname; wildc
AI-assisted analysis of paperclipai/paperclip@67001ec6eb (2026-08-12).
Data as JSON: /api/errors/b606bb93d06087c0.
Report an issue: GitHub.