paperclipai/paperclip · error · CreateosCleanupError
CreateOS command cleanup failed; process termination is…
Error message
CreateOS command cleanup failed; process termination is unconfirmed.
What it means
CreateosCleanupError thrown when post-run process termination fails for any reason other than a 404 (process already gone). The host must know that containment is unproven — the process may still be running in the sandbox. The 404 case is tolerated because a missing process means it already exited.
Solutions
- Destroy the lease entirely — treat it as poisoned, since termination is unconfirmed.
- Increase client.config.timeoutMs if cleanup routinely exceeds the timeout.
- Retry termination once before destroying the lease.
- Check sandbox/lease status via API to confirm whether the process survived.
Example fix
// before
catch (error) { if (!(error instanceof CreateosApiError && error.status === 404)) throw new CreateosCleanupError("..."); }
// after
catch (error) {
if (error instanceof CreateosApiError && error.status === 404) break; // already gone
await destroyLease(lease); // fail safe: reclaim the whole sandbox
throw new CreateosCleanupError("...");
} Defensive patterns
Strategy: try-catch
Type guard
function isCreateosCleanupError(e) {
return e instanceof CreateosCleanupError;
} Try / catch
try {
return await execute(lease, cmd, { signal });
} catch (e) {
if (isCreateosCleanupError(e)) {
await destroyLease(lease); // treat lease as poisoned
}
throw e;
} Prevention
- Increase client timeoutMs if cleanup terminations routinely time out.
- Destroy rather than reuse leases after cleanup failures.
- Monitor for 5xx from the termination endpoint to catch server-side issues.
When it happens
Trigger: DELETE /sandboxes/:id/processes/:pid fails with a network error, non-404 HTTP status, times out (cleanupSignal), or the inner 'Process tree has not exited.' error is raised — anything except CreateosApiError with status 404.
Common situations: Sandbox became unreachable after the run; cleanup AbortSignal.timeout(client.config.timeoutMs) fired during a slow termination; server returned 500 during termination; permission/lease state changed mid-cleanup.
Understand the failure class
Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.
Related errors
- Process tree has not exited.
- CreateOS command probe failed.
- CreateOS lease cleanup is already in progress.
- CreateOS lease cleanup must finish before resume.
- CreateOS process cleanup is unconfirmed; destroy this lease…
AI-assisted analysis of paperclipai/paperclip@3f1d897a7c (2026-09-18).
Data as JSON: /api/errors/4f3ae50849c7ee56.
Report an issue: GitHub.
Appendix: source
Thrown at packages/plugins/sandbox-providers/createos/src/execute.ts:217
if (signal.aborted && signal.reason?.name === "TimeoutError") {
output.finish();
return {
exitCode: null, timedOut: true, stdout: output.stdout, stderr: output.stderr,
metadata: { processId, outputTruncated: output.truncated },
};
}
if (signal.aborted) throw new Error("CreateOS command was cancelled.");
throw error;
} finally {
const cleanupSignal = AbortSignal.timeout(client.config.timeoutMs);
// Do not hide a cleanup failure: the host must know containment is unproven.
try {
if (processId && !completed) {
try {
const termination = await client.json(`${base}/${processId}?grace_ms=1000`, "DELETE", undefined, cleanupSignal);
if (termination.tree_exited !== true) throw new Error("Process tree has not exited.");
}
catch (error) { if (!(error instanceof CreateosApiError && error.status === 404)) throw new CreateosCleanupError("CreateOS command cleanup failed; process termination is unconfirmed."); }
}
} finally {
if (staged && stdinPath) {
// /files has no delete verb. /exec supplies a bounded, one-shot removal
// after the managed process finishes, without retaining another record.
await client.json(`/sandboxes/${id}/exec`, "POST", {
cmd: "/bin/rm", args: ["-f", "--", stdinPath],
}, cleanupSignal).catch(() => undefined);
}
}
}
}
View on GitHub (pinned to 3f1d897a7c)