paperclipai/paperclip · critical

prepareSandboxManagedRuntime requires a client that exposes

Error message

prepareSandboxManagedRuntime requires a client that exposes syncIn (createCommandManagedRuntimeClient provides a native-or-fallback implementation).

What it means

Thrown in prepareSandboxManagedRuntime when input.client has no syncIn function. The orchestrator delegates all inbound staging (workspace, assets, additional sources) to client.syncIn — either a native provider transport (Daytona/Kubernetes uploadFiles) or a base64-tar fallback. Requiring syncIn explicitly makes a misconfigured client fail loud instead of silently skipping staging.

Source

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

    input.workspaceExclude,
    gitIgnoredExcludes,
  );
  const baselineSnapshot = syncWorkspace
    ? await captureDirectorySnapshot(input.workspaceLocalDir, { exclude: restoreExclude })
    : null;

  // Every inbound staging step delegates to the provider through `client.syncIn`:
  // the orchestrator no longer inlines `writeFile`+`run` or chooses a transport,
  // and there is no `usesCustomProvision` native-diversion gate. `syncIn` is
  // ALWAYS present in production — the command-managed client exposes a native
  // transport (Daytona/Kubernetes `uploadFiles` + provider-executed post-upload
  // commands) or a byte-identical base64-tar fallback that reproduces the prior
  // `writeFile`+`run` sequence. Require it explicitly so a misconfigured client
  // fails loud rather than silently skipping staging. `syncOut` stays optional
  // (native-only) with a tar fallback on the restore path below.
  const syncIn = input.client.syncIn;
  if (typeof syncIn !== "function") {
    throw new Error(
      "prepareSandboxManagedRuntime requires a client that exposes syncIn " +
        "(createCommandManagedRuntimeClient provides a native-or-fallback implementation).",
    );
  }
  const nativeSyncOut = typeof input.client.syncOut === "function";
  let syncOperationSeq = 0;
  // Opaque, ordered, non-sensitive operation tokens — never a caller/asset id.
  const nextSyncOperationId = () => `sync-op-${++syncOperationSeq}`;

  // Remote directory of each additional (referenced) project that stages
  // successfully, keyed by projectId. A project that fails to stage is absent.
  const additionalSourceDirs: Record<string, string> = {};
  // Each additional (referenced) project whose staging failed, paired with the
  // failure message. Per-project failure isolation keeps the run and the other
  // projects going; this list makes each failure a first-class, reported outcome.
  const additionalSourceFailures: AdditionalSourceStagingFailure[] = [];
  // Additional projects stage as plain trees. Drop the heavy build/cache dirs a
  // reference tree does not need, and `.git` — additional sources never carry

View on GitHub (pinned to 67001ec6eb)

Solutions

  1. Construct the client via createCommandManagedRuntimeClient(input), which always provides a native-or-fallback syncIn.
  2. If using a custom client, implement syncIn matching the SandboxManagedRuntimeClient.syncIn signature.
  3. Add a type assertion / typeof check at client assembly time so misconfiguration is caught before prepare is called.
  4. Update tests that hand-build stub clients to include a no-op or real syncIn.

Example fix

// before
const client = { run: stubRun, exec: stubExec };
await prepareSandboxManagedRuntime({ ...input, client });
// after
const client = createCommandManagedRuntimeClient(input);
await prepareSandboxManagedRuntime({ ...input, client });
Defensive patterns

Strategy: type-guard

Validate before calling

if (typeof input.client.syncIn !== 'function') {
  throw new Error('client.syncIn is required; build via createCommandManagedRuntimeClient');
}

Type guard

function hasSyncIn(client: unknown): client is { syncIn: (...args: unknown[]) => unknown } {
  return typeof (client as { syncIn?: unknown })?.syncIn === 'function';
}

Prevention

When it happens

Trigger: Calling prepareSandboxManagedRuntime with a client object built without createCommandManagedRuntimeClient, or a custom client whose syncIn was deleted/undefined. The runtime then refuses to proceed because it cannot transfer files into the sandbox.

Common situations: Adapter was upgraded and the client factory changed; a test stub client omits syncIn; a partial client implementation that only implements run/exec was passed; dependency injection wired the wrong client interface.

Related errors


AI-assisted analysis of paperclipai/paperclip@67001ec6eb (2026-08-12). Data as JSON: /api/errors/e043c70e88acede9. Report an issue: GitHub.