paperclipai/paperclip · error
Daytona sandbox is in an unrecoverable error state
Error message
Daytona sandbox ${sandbox.id} is in an unrecoverable error state: ${sandbox.errorReason ?? "unknown error"} What it means
Lifecycle guard in ensureSandboxStarted: the Daytona sandbox object reports state 'error' (with sandbox.errorReason as detail, or 'unknown error' when absent), meaning the provider marked the sandbox unrecoverable. Every lease-holding hook (resume, realize, execute, sync, ingress, setup) routes through this check and aborts rather than attempting to start a dead sandbox.
Solutions
- Destroy and recreate the sandbox; inspect the reported errorReason in Daytona for root cause.
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at packages/plugins/sandbox-providers/daytona/src/plugin.ts:449 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-08-18).
Data as JSON: /api/errors/768a5059e6660907.
Report an issue: GitHub.
Appendix: source
Thrown at packages/plugins/sandbox-providers/daytona/src/plugin.ts:467
run: () => Promise<T>,
): Promise<T> {
if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {
return run();
}
let timer: ReturnType<typeof setTimeout> | undefined;
const deadline = new Promise<never>((_, reject) => {
timer = setTimeout(() => reject(new SandboxLivenessTimeoutError(operation, timeoutMs)), timeoutMs);
});
try {
return await Promise.race([run(), deadline]);
} finally {
if (timer !== undefined) clearTimeout(timer);
}
}
async function ensureSandboxStarted(sandbox: Sandbox, timeoutSeconds: number): Promise<void> {
if (sandbox.state === "started") return;
// Bound the lifecycle call just past its own SDK deadline. A normal slow start
// finishes within `timeoutSeconds`; only a connection-level hang the SDK
// deadline misses reaches this wrapper bound.
const startBoundMs = timeoutSeconds * 1_000 + LIVENESS_START_TIMEOUT_MARGIN_MS;
if (sandbox.state === "error") {
if (sandbox.recoverable) {
await withLivenessTimeout("sandbox.recover", startBoundMs, () => sandbox.recover(timeoutSeconds));
return;
}
throw new Error(`Daytona sandbox ${sandbox.id} is in an unrecoverable error state: ${sandbox.errorReason ?? "unknown error"}`);
}
await withLivenessTimeout("sandbox.start", startBoundMs, () => sandbox.start(timeoutSeconds));
}
async function resolveSandboxWorkingDirectory(sandbox: Sandbox): Promise<string> {
const root = (await sandbox.getWorkDir())?.trim()
|| (await sandbox.getUserHomeDir())?.trim()
|| "/home/daytona";
const remoteCwd = path.posix.join(root, "paperclip-workspace");View on GitHub (pinned to 01ad858492)