{"record":{"id":"768a5059e6660907","repo":"paperclipai/paperclip","slug":"daytona-sandbox-sandbox-id-is-in-an-unrecoverab","errorCode":null,"errorMessage":"Daytona sandbox ${sandbox.id} is in an unrecoverable error state: ${sandbox.errorReason ?? \"unknown error\"}","messagePattern":"Daytona sandbox (.+?) is in an unrecoverable error state: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/plugins/sandbox-providers/daytona/src/plugin.ts","lineNumber":467,"sourceCode":"  run: () => Promise<T>,\n): Promise<T> {\n  if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {\n    return run();\n  }\n  let timer: ReturnType<typeof setTimeout> | undefined;\n  const deadline = new Promise<never>((_, reject) => {\n    timer = setTimeout(() => reject(new SandboxLivenessTimeoutError(operation, timeoutMs)), timeoutMs);\n  });\n  try {\n    return await Promise.race([run(), deadline]);\n  } finally {\n    if (timer !== undefined) clearTimeout(timer);\n  }\n}\n\nasync function ensureSandboxStarted(sandbox: Sandbox, timeoutSeconds: number): Promise<void> {\n  if (sandbox.state === \"started\") return;\n  // Bound the lifecycle call just past its own SDK deadline. A normal slow start\n  // finishes within `timeoutSeconds`; only a connection-level hang the SDK\n  // deadline misses reaches this wrapper bound.\n  const startBoundMs = timeoutSeconds * 1_000 + LIVENESS_START_TIMEOUT_MARGIN_MS;\n  if (sandbox.state === \"error\") {\n    if (sandbox.recoverable) {\n      await withLivenessTimeout(\"sandbox.recover\", startBoundMs, () => sandbox.recover(timeoutSeconds));\n      return;\n    }\n    throw new Error(`Daytona sandbox ${sandbox.id} is in an unrecoverable error state: ${sandbox.errorReason ?? \"unknown error\"}`);\n  }\n  await withLivenessTimeout(\"sandbox.start\", startBoundMs, () => sandbox.start(timeoutSeconds));\n}\n\nasync function resolveSandboxWorkingDirectory(sandbox: Sandbox): Promise<string> {\n  const root = (await sandbox.getWorkDir())?.trim()\n    || (await sandbox.getUserHomeDir())?.trim()\n    || \"/home/daytona\";\n  const remoteCwd = path.posix.join(root, \"paperclip-workspace\");","sourceCodeStart":449,"sourceCodeEnd":485,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/packages/plugins/sandbox-providers/daytona/src/plugin.ts#L449-L485","documentation":"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.","triggerScenarios":"Thrown at packages/plugins/sandbox-providers/daytona/src/plugin.ts:449 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Destroy and recreate the sandbox; inspect the reported errorReason in Daytona for root cause."],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"01ad8584922b5d85292b1723cae71fa0d9b07a19","analyzedAt":"2026-08-18T22:49:45.177Z","contentChangedAt":"2026-08-18T22:49:45.177Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}