Commit fcb95c3
cli: replace sandbox.kill() with setTimeout(1s) in create command to prevent snapshot deletions (#1256)
## Summary
In the CLI's `sandbox create` command, the `connectSandbox` function's
`finally` block previously called `sandbox.kill()` when the terminal
session ended. This replaces it with `sandbox.setTimeout(1_000)` so the
sandbox expires implicitly after 1 second rather than being explicitly
killed.
The motivation is that an explicit `kill()` can trigger deletion of
historic sandbox snapshots, whereas letting the sandbox time out avoids
that side effect.
### Updates since last revision
Addressed review feedback about a race condition: `clearInterval` stops
future keep-alive ticks but cannot cancel one already in-flight. The
keep-alive callback now stores its promise in a `pendingKeepAlive`
variable, and the `finally` block awaits it (with `.catch(() => {})`)
before setting the 1s shutdown timeout. This ensures an in-flight
`setTimeout(30_000)` cannot silently override the shutdown timeout.
## Review & Testing Checklist for Human
- [ ] **Verify that `sandbox.setTimeout(1_000)` does not trigger
snapshot deletion** — this is the core assumption behind the change.
Confirm that the implicit expiry path in the backend behaves differently
from the explicit `kill()` path with respect to snapshot preservation.
- [ ] **Test `e2b sandbox create` end-to-end**: connect a terminal,
exit, and confirm the sandbox is cleaned up within a few seconds and no
snapshots are lost.
- [ ] **Review the race condition fix**: confirm that `await
pendingKeepAlive.catch(() => {})` correctly serializes against the last
in-flight keep-alive before the 1s timeout is applied. Note that the
interval callback is no longer `async` — it just assigns the promise.
- [ ] **Edge case: what happens if `setTimeout` fails?** The sandbox
would remain alive with its previous 30s keep-alive timeout. Decide if
that's acceptable or if a fallback is needed.
### Notes
- The 1-second timeout value was chosen per the request. Adjust if a
different grace period is preferred.
- The keep-alive interval (`clearInterval`) is still stopped before
awaiting the pending promise, so no new ticks will fire.
Link to Devin session:
https://app.devin.ai/sessions/68081ba06fa54be9b8127ba1d68481ae
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: ben@e2b.dev <ben@e2b.dev>1 parent b5f2631 commit fcb95c3
File tree
2 files changed
+11
-4
lines changed- .changeset
- packages/cli/src/commands/sandbox
2 files changed
+11
-4
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
98 | 98 | | |
99 | 99 | | |
100 | 100 | | |
101 | | - | |
102 | | - | |
103 | | - | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
104 | 105 | | |
105 | 106 | | |
106 | 107 | | |
| |||
112 | 113 | | |
113 | 114 | | |
114 | 115 | | |
115 | | - | |
| 116 | + | |
| 117 | + | |
116 | 118 | | |
117 | 119 | | |
118 | 120 | | |
| |||
0 commit comments