paperclipai/paperclip · error
CreateOS transfer command failed.
Error message
CreateOS transfer command failed.
What it means
The CreateOS sandbox plugin's internal `run` helper executes a shell command inside the remote sandbox during file synchronization (e.g. mkdir/tar/mv steps). If the command exits non-zero or times out, the plugin discards the actual exit details and throws this generic message. It signals that a remote-side transfer step failed without telling you which command or why.
Solutions
- Retry the sync with the sandbox exec endpoint to run the failing command manually and inspect its real stderr/exit code, since this error hides those details.
- Increase the timeoutMs on the transfer operation if the failure correlates with large files.
- Verify the sandbox image provides all tools the transfer relies on (bash, tar) and that the remote target directory is writable.
- Check sandbox disk usage and quotas; clean stale files and retry.
Example fix
// before: opaque failure
await run(`tar -xzf ${archive} -C ${remoteDir}`, remoteDir, 5_000);
// after: pre-check target writability and raise the timeout
await run(`mkdir -p ${remoteDir} && test -w ${remoteDir}`, remoteDir, 10_000);
await run(`tar -xzf ${archive} -C ${remoteDir}`, remoteDir, 60_000); Defensive patterns
Strategy: retry
Validate before calling
// pre-flight: ensure remote tools exist await run(`command -v bash && command -v tar`, ROOT, 10_000);
Try / catch
try {
await syncFiles(params);
} catch (err) {
if (err.message === "CreateOS transfer command failed.") {
// inspect remote state, then retry with longer timeoutMs
} else throw err;
} Prevention
- Set generous timeoutMs for large transfers
- Verify sandbox image tooling (bash, tar) before syncing
- Check sandbox disk quota periodically
When it happens
Trigger: Any bash command run by syncFiles inside the sandbox (e.g. `mkdir -p`, `tar -x`, `mv`, `chmod` for the mapping) returns a non-zero exit code, or exceeds the optional timeoutMs passed by the caller and is aborted via AbortSignal.timeout.
Common situations: Remote sandbox image lacks a tool the transfer step needs (tar, bash built-ins); target directory is read-only or owned by another user; disk quota exceeded on the sandbox; timeoutMs set too low for large uploads; remote path already exists in a conflicting state.
Related errors
- CreateOS command cleanup failed; process termination is…
- CreateOS command probe failed.
- CreateOS process stream reported an error.
- CreateOS sandbox did not reach
- CreateOS transfer path escapes the workspace.
AI-assisted analysis of paperclipai/paperclip@3f1d897a7c (2026-09-18).
Data as JSON: /api/errors/30899ce1b72e7507.
Report an issue: GitHub.
Appendix: source
Thrown at packages/plugins/sandbox-providers/createos/src/file-sync.ts:71
function excluded(name: string, patterns: string[]): boolean {
name = name.replace(/^\.\//, "").replace(/\/$/, "");
return patterns.some((pattern) => [pattern, `${pattern}/**`, `**/${pattern}`, `**/${pattern}/**`]
.some((glob) => path.matchesGlob(name, glob)));
}
export async function syncFiles(
client: CreateosClient,
params: PluginEnvironmentSyncInParams,
direction: "in" | "out",
signal: AbortSignal,
): Promise<PluginEnvironmentSyncResult> {
const id = identifier(params.lease.providerLeaseId);
const operations: PluginEnvironmentSyncResult["operations"] = [];
const run = async (command: string, cwd = ROOT, timeoutMs?: number) => {
assertRemotePath(cwd);
const result = await execute(client, { ...params, command: "/bin/bash", args: ["-c", command], cwd },
timeoutMs == null ? signal : AbortSignal.any([signal, AbortSignal.timeout(timeoutMs)]));
if (result.timedOut || result.exitCode !== 0) throw new Error("CreateOS transfer command failed.");
};
const upload = async (local: string, remote: string) => {
const source = createReadStream(local);
try {
const init: RequestInit & { duplex: "half" } = {
method: "PUT", body: Readable.toWeb(source) as ReadableStream<Uint8Array>,
duplex: "half", headers: { "Content-Type": "application/octet-stream" }, signal,
};
const response = await client.request(`/sandboxes/${id}/files?path=${encodeURIComponent(remote)}`, init);
await response.body?.cancel();
} finally { source.destroy(); }
};
const download = async (remote: string, local: string, mode = 0o600) => {
const response = await client.request(`/sandboxes/${id}/files?path=${encodeURIComponent(remote)}`, { signal });
if (!response.body) throw new Error("CreateOS file download has no body.");
await pipeline(response.body, createWriteStream(local, { flags: "wx", mode }), { signal });
};
View on GitHub (pinned to 3f1d897a7c)