paperclipai/paperclip · error · Error

additional source projectId is not a simple path segment

Error message

additional source projectId is not a simple path segment: ${projectId}

What it means

An additional project source entry supplied a localPath that is not POSIX-absolute; the sandbox sync cannot stage a relative path into the managed runtime, so the entry is rejected (per-project failure isolation logs and skips it).

Solutions

  1. Use a simple path segment (no separators or traversal) for projectId.
Defensive patterns

Strategy: try-catch

When it happens

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

Common situations: See trigger scenarios.


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

Appendix: source

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

    // `postUploadCommands`, confine the operation's source and target to their
    // own roots (fail-closed), and delegate to `syncIn` (native transfer, or the
    // base64-tar fallback). `finish` emits the terminal progress line.
    const stageConfinedSyncIn = async (params: {
      files: SandboxSyncFileMapping[];
      postUploadCommands?: SandboxPostUploadCommand[];
      sourceRoots: string[];
      targetRoots: string[];
      progressLabel: string;
      statusPhase: RuntimeStatusPhase;
      progressBytes: number;
    }): Promise<void> => {
      const operations: SandboxSyncOperation[] = [{
        operationId: nextSyncOperationId(),
        files: params.files,
        ...(params.postUploadCommands
          ? { postUploadCommands: withRunTimeout(params.postUploadCommands) }
          : {}),
      }];
      assertSyncOperationsConfined(operations, {
        sourceRoots: params.sourceRoots,
        targetRoots: params.targetRoots,
      });
      const upload = makeTransferProgress(
        input.onProgress,
        "Syncing",
        "to",
        params.progressLabel,
        { sink: input.onRuntimeProgress, phase: params.statusPhase },
      );
      const syncResult = await syncIn(operations);
      // Prefer the transport's own byte total. It is the real count for a
      // provider that has no host tarball to stat (a referenced project rides
      // a `directory` mapping). Fall back to the caller-supplied count when
      // the transport reports 0, so a provider that under-reports still
      // shows the host-known workspace total.
      const transferredBytes = sumSyncResultBytes(syncResult);

View on GitHub (pinned to 3f1d897a7c)