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 carryView on GitHub (pinned to 67001ec6eb)
Solutions
- Construct the client via createCommandManagedRuntimeClient(input), which always provides a native-or-fallback syncIn.
- If using a custom client, implement syncIn matching the SandboxManagedRuntimeClient.syncIn signature.
- Add a type assertion / typeof check at client assembly time so misconfiguration is caught before prepare is called.
- 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
- Always construct clients with createCommandManagedRuntimeClient.
- Type the prepare input so a missing syncIn is a compile error.
- In tests, build stub clients from the same factory or include a no-op syncIn.
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
- ${action} failed with exit code ${result.exitCode ?? "null"}
- Could not determine remote file size for ${remotePath}
- Remote file read was truncated for ${remotePath}: ${out.byte
- sync operation ${label} path is not a confined absolute path
- sync operation ${label} path escapes its confinement root: $
AI-assisted analysis of paperclipai/paperclip@67001ec6eb (2026-08-12).
Data as JSON: /api/errors/e043c70e88acede9.
Report an issue: GitHub.