{"record":{"id":"825e18f0f8b59185","repo":"paperclipai/paperclip","slug":"failed-to-stop-daytona-sandbox-during-lease-releas","errorCode":null,"errorMessage":"Failed to stop Daytona sandbox during lease release: ${formatErrorMessage(error)}. Attempting delete instead.","messagePattern":"Failed to stop Daytona sandbox during lease release: (.+?)\\. Attempting delete instead\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"packages/plugins/sandbox-providers/daytona/src/plugin.ts","lineNumber":2277,"sourceCode":"            evictSandboxHandle(scope);\n            return {\n              providerLeaseId: null,\n              metadata: { expired: true, workspaceSentinel },\n            };\n          }\n          const shellCommand = await detectSandboxShellCommand(\n            sandbox,\n            toTimeoutSeconds(config.timeoutMs),\n          );\n          sandboxHandleCache.markFresh(scope);\n          sandboxHandleLeaseAdmissionStates.open(scope);\n          return {\n            providerLeaseId: sandbox.id,\n            metadata: leaseMetadata({\n              config,\n              sandbox,\n              shellCommand,\n              remoteCwd,\n              resumedLease: true,\n              resumedFromState,\n              sandboxState: \"started\",\n              workspaceSentinel,\n            }),\n          };\n        } catch (error) {\n          evictSandboxHandle(scope);\n          // A timeout, rate limit, or provider 5xx does not prove this sandbox is\n          // lost. Preserve the exact resource and let the host retry its recorded\n          // lease; replacement is permitted only after an explicit not-found or\n          // an immutable workspace identity mismatch.\n          throw error;\n        }\n      },\n      { allowClosed: true },\n    );\n  },","sourceCodeStart":2259,"sourceCodeEnd":2295,"githubUrl":"https://github.com/paperclipai/paperclip/blob/3f1d897a7c018d76563a21c6e39c3c9b03933622/packages/plugins/sandbox-providers/daytona/src/plugin.ts#L2259-L2295","documentation":"During Daytona sandbox lease release with reuseLease=true, the plugin calls sandbox.stop() to preserve the sandbox for reuse. If stop() throws (API error, timeout, sandbox already gone server-side), it logs this warning and falls back to sandbox.delete() so the sandbox does not leak; if delete also fails, a follow-up warning fires and the sandbox may be orphaned.","triggerScenarios":"reuseLease=true, sandbox state is not 'stopped', and sandbox.stop(toTimeoutSeconds(config.timeoutMs)) rejects — Daytona API 5xx/timeout, sandbox expired or already deleted remotely, or network interruption between paperclip and Daytona.","commonSituations":"Daytona cloud incident or rate limiting; timeoutMs too small for the sandbox to shut down; sandbox expired server-side while the lease still references it; stale local state after Daytona workspace events.","solutions":["Check the sandbox's real state in the Daytona dashboard; if the follow-up delete warning also fired, delete the orphan manually.","Increase the plugin's timeoutMs so stop/delete have room to complete.","Check Daytona service status and API credentials if failures repeat.","If sandbox reuse is not required, set reuseLease=false so release deletes directly and stop is never the dependent step."],"exampleFix":"// before (daytona sandbox provider config)\n{ \"reuseLease\": true, \"timeoutMs\": 5000 }\n\n// after\n{ \"reuseLease\": true, \"timeoutMs\": 30000 }","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await lease.release();\n} catch (err) {\n  // Stop-failure already fell back to delete inside the plugin; verify the sandbox\n  // is actually gone before treating the release as clean.\n  const stillExists = await daytonaClient.sandboxExists(lease.sandboxId);\n  if (stillExists) {\n    await janitor.queueManualDelete(lease.sandboxId); // reconcile later\n  }\n}","preventionTips":["Watch for the follow-up 'Failed to delete Daytona sandbox after stop failure' warn — that pair means a true orphan.","Run a periodic reconciliation job comparing Daytona sandboxes against active leases.","Size timeoutMs above the p99 sandbox stop/delete latency.","Prefer reuseLease=false unless reuse is a measured requirement — it removes stop() from the release path."],"tags":["daytona","sandbox","lease-release","stop-failed","timeout"],"backgroundTag":"sandbox-teardown-failure","analyzedSha":"3f1d897a7c018d76563a21c6e39c3c9b03933622","analyzedAt":"2026-08-18T22:49:45.177Z","contentChangedAt":"2026-08-18T22:49:45.177Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}