feat(sdk): filesystem-only snapshots (pause memory:false)#1465
feat(sdk): filesystem-only snapshots (pause memory:false)#1465bchalios wants to merge 2 commits into
Conversation
🦋 Changeset detectedLatest commit: 9e798d5 The changes in this PR will be included in the next version bump. This PR includes changesets to release 2 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
PR SummaryMedium Risk Overview
Reviewed by Cursor Bugbot for commit 9e798d5. Bugbot is set up for automated code reviews on this repo. Configure here. |
Package ArtifactsBuilt from 3bfdd0c. Download artifacts from this workflow run. JS SDK ( npm install ./e2b-2.30.4-feat-pause-filesystem-only.0.tgzCLI ( npm install ./e2b-cli-2.12.2-feat-pause-filesystem-only.0.tgzPython SDK ( pip install ./e2b-2.29.3+feat.pause.filesystem.only-py3-none-any.whl |
4b7cf94 to
d434332
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4b7cf94857
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| async pause(opts?: ConnectionOpts & { memory?: boolean }): Promise<boolean> { | ||
| return await SandboxApi.pause(this.sandboxId, this.resolveApiOpts(opts)) |
There was a problem hiding this comment.
Rebuild the sandbox handle after filesystem-only resumes
When memory:false is used on an existing sandbox, callers resume a cold-booted envd through the same object, but the instance connect() path in this file only awaits SandboxApi.connectSandbox(...) and returns this without applying the resume response's envdAccessToken/traffic token or rebuilding the envd/RPC clients. For secure sandboxes where a filesystem-only cold boot reinitializes envd and returns fresh credentials, subsequent commands/files calls on this object still send the pre-pause headers, so the resume appears to succeed but guest operations fail; refresh the instance state or direct this flow through static Sandbox.connect(sandboxId).
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
the backend should probably keep the current envdAccessToken when resuming from fs-only snapshot
There was a problem hiding this comment.
@mishushakov @chatgpt-codex-connector confirmed — the backend keeps the same envdAccessToken across a filesystem-only resume. RebootSandbox re-establishes envd /init auth on the cold boot with the same access token (via the MMDS path), and the resume/connect response returns that same token. The infra PR has an integration test for exactly this — TestSecureSandboxFilesystemOnlyResumeAuth: it pauses a secure sandbox with memory:false, cold-boot resumes it, then authorizes an envd request with the original token captured before the pause and reads back a file written pre-pause.
So the existing handle's credentials stay valid after a filesystem-only resume — no rebuild needed. This isn't a new code path on the SDK side: memory:false only changes how the backend persists/restores the snapshot; the SDK resume flow (connect) is unchanged and identical to a memory resume. The instance connect() returning this is pre-existing behavior shared with memory resume, and it remains correct because the token and sandbox domain are stable across the resume.
There was a problem hiding this comment.
To use Codex here, create a Codex account and connect to github.
d434332 to
d54797f
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit d54797f. Configure here.
d54797f to
57674a0
Compare
mishushakov
left a comment
There was a problem hiding this comment.
everything looks good - only thing is that i believe the envd token should be persistent across pause/resume cycle.
please use SandboxPauseOpts consistently.
| * ``` | ||
| */ | ||
| async pause(opts?: ConnectionOpts): Promise<boolean> { | ||
| async pause(opts?: ConnectionOpts & { memory?: boolean }): Promise<boolean> { |
There was a problem hiding this comment.
we're not using the SandboxPauseOpts here
There was a problem hiding this comment.
This was anchored to the pre-amend commit — it's addressed in the latest commit (57674a071): both pause and betaPause now take the exported SandboxPauseOpts (and the static SandboxApi.pause/betaPause too), matching how createSnapshot uses CreateSnapshotOpts. resolveApiOpts spreads the opts through, so memory reaches SandboxApi.pause.
| /** | ||
| * @deprecated Use {@link Sandbox.pause} instead. | ||
| */ | ||
| async betaPause(opts?: ConnectionOpts): Promise<boolean> { |
There was a problem hiding this comment.
we're not using SandboxPauseOpts here
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
57674a0 to
59a8378
Compare
|
Per offline feedback from @mishushakov, renamed the SDK-facing parameter to make the drop-on-
The wire/spec field stays |

Summary
Adds an optional
memoryflag topausein both the JS and Python SDKs. Whenmemoryisfalse, the pause captures only the filesystem (no memory snapshot); resuming such a snapshot cold-boots (reboots) the sandbox from disk — losing in-memory state, running processes, and open connections. Defaults totrue(full memory snapshot), so existing callers are unaffected.This is the SDK surface for the filesystem-only snapshot feature on the infra side.
Usage
memorydefaults totrue—pause()/pause({})behave exactly as before.What changed
memory: boolean(defaulttrue) onPOST /sandboxes/{sandboxID}/pause(SandboxPauseRequest); both API clients regenerated viamake codegen.Sandbox.pause/betaPauseaccept{ memory }→SandboxApi.pausesends the request body.pause(memory=...)/beta_pause→_cls_pause(sync + async) sendsSandboxPauseRequest(memory=...).tests/sandbox/snapshot.test.ts) and Python sync + async. All pass against a local stack;format/lint/typecheckclean.minorfore2band@e2b/python-sdk.Note (related infra observation, not addressed here)
While testing, a filesystem-only resume cold-boots into a different default exec context (
root//root) than a memory resume (user//home/user). The filesystem itself is fully intact; tests use absolute paths to be robust to this. Worth confirming on the infra reboot path whether the template's default user should be restored after a cold boot.🤖 Generated with Claude Code