Releases: cloudflare/sandbox-sdk
@cloudflare/sandbox@0.9.2
@cloudflare/sandbox@0.9.1
Patch Changes
-
51f1d04Thanks @whoiskatrin! - Coalesce concurrentSandbox.destroy()calls onto a single teardown. If a
previousdestroy()is still in flight, subsequent calls await the same
underlying work instead of starting a second teardown, and emit a canonical
sandbox.destroy.coalescedevent per coalesced call for observability.
Once the in-flight teardown settles, laterdestroy()calls run a fresh
teardown as before. Fixes observed destroy-recreate thrash where external
health checks can invokedestroy()faster than the sandbox can initialize. -
#592
b2bf021Thanks @whoiskatrin! - Addsandbox.getContainerPlacementId()to retrieve the Cloudflare placement ID
observed for the underlying container.The placement ID identifies the current container placement and changes when
the container is replaced by the platform. Compare the returned value against
a stored value to detect container replacement and trigger reconciliation.The placement ID is captured during the session-create handshake and cached
in Durable Object storage, so reads are cheap and do not require a healthy
container. A fresh placement ID is captured on each subsequent handshake,
so a replacement is reflected the next time the sandbox is used.Returns
undefinedwhen no session-create handshake has been observed yet on
this sandbox — call any method that triggers session creation (such as
exec()) first. Returnsnullwhen a handshake has completed but the
container'sCLOUDFLARE_PLACEMENT_IDenvironment variable is not set, such as
in local development with wrangler.await sandbox.exec('true'); // ensures the handshake has run const containerPlacementId = await sandbox.getContainerPlacementId(); if ( typeof containerPlacementId === 'string' && containerPlacementId !== lastKnownPlacementId ) { // Container was replaced — reconcile state }
@cloudflare/sandbox@0.9.0
Minor Changes
-
#633
4e628aeThanks @whoiskatrin! - Handle shell exits withSessionTerminatedError, and let the same session id recover on the next call.import { SessionTerminatedError } from '@cloudflare/sandbox'; const session = await sandbox.createSession({ id: 'build' }); try { await session.exec('exit 42'); } catch (error) { if (error instanceof SessionTerminatedError) { console.log(error.exitCode); // 42 await session.exec('echo fresh shell'); } }
If a session's shell exits, the failing call now returns
SESSION_TERMINATED
(HTTP 410) with the observed exit code instead of a generic internal error.
Retrying with the same session id, or callingcreateSession({ id }), starts a
fresh session without destroying the whole sandbox. Session-local state such as
the working directory, environment variables, shell functions, and background
jobs is lost when the shell exits.
@cloudflare/sandbox@0.8.14
Patch Changes
-
#613
174313fThanks @ghostwriternr! - Avoid duplicate session-create calls when parallel operations hit a
fresh sandbox. Parallel callers now share one setup call instead of
each issuing their own. Sequential operations are unaffected.Session setup also now retries cleanly on the next operation if it is
interrupted partway through — including by a container stop during
first use — instead of leaving the sandbox in a state that looks
initialized but references a session the container no longer has. -
#624
bbdfd95Thanks @ghostwriternr! - Fix sandboxes staying alive past their configuredsleepAftervalue.Workers that passed configuration options to
getSandbox()on every request (sleepAfter,keepAlive, orcontainerTimeouts) could unintentionally extend sandbox lifetimes. The SDK's internal reapply path treated identical reapplied values as activity, resetting the sleep timer each time. Under sustained traffic, sandboxes would never sleep at all.After updating, reapplying the same configuration value is a true no-op. Your
getSandbox()calls continue to work exactly as before; sandboxes now respect their configured sleep timers regardless of how often configuration is reapplied.This release also removes the unused
baseUrloption fromSandboxOptions, along with thesetBaseUrlRPC method on the Sandbox Durable Object. The option had no effect on runtime behavior; preview URLs are driven by thehostnamepassed to preview-URL APIs. If you were settingbaseUrlongetSandbox(), you can safely remove it. Directly invoking the undocumentedsetBaseUrlRPC method will now error. -
#629
34e3a96Thanks @aron-cf! - Improve reliability ofdesktop.stop()as well as general isolation of the desktop processes by
running them in a subprocess. This should ensure that processes are cleaned up when calling
desktop.stop()and crashes should not impact the sandbox container service. -
#576
9222fd0Thanks @whoiskatrin! - Fix stream controller race condition causing "Invalid state: Controller is already closed" errorsResolves an issue where client disconnections during streaming operations could cause unhandled TypeError exceptions, potentially corrupting the SDK bridge state. The fix adds defensive error handling in the execute streaming handler to gracefully handle callbacks firing after stream cancellation.
-
#614
74a58e9Thanks @aron-cf! - Adds a newtransport: 'http' | 'websocket'field to thegetSandbox()options. This can be
used to dynamically select transport on a per-sandbox basis.[!NOTE]
Changing transport on an already existing sandbox may result in dropped connections, it is
recommended to keep the same transport for the lifetime of the sandbox instance.const sandbox = getSandbox(env.Sandbox, 'my-sandbox', { transport: 'websocket' });
-
#567
1c7337aThanks @scuffi! - Adds support for local backup and restore through theBACKUP_BUCKETR2 binding in local development whenlocalBucket: trueis set.
@cloudflare/sandbox@0.8.11
Patch Changes
-
#585
ab84333Thanks @aron-cf! - Add the sandbox bridge — an HTTP API that translates REST calls into Sandbox Durable Object operations. Deploy the bridge as a standalone Cloudflare Worker to expose session management, command execution, file read/write, PTY, and workspace mount/unmount over HTTP. Includes an optional warm pool Durable Object for pre-provisioning sandboxes to reduce cold-start latency.Import the bridge factory and warm pool from
@cloudflare/sandbox/bridge.import { bridge } from '@cloudflare/sandbox/bridge'; export { Sandbox } from '@cloudflare/sandbox'; export { WarmPool } from '@cloudflare/sandbox/bridge'; export default bridge({ fetch(request, env, ctx) { // your code here return new Response('OK'); } });
@cloudflare/sandbox@0.8.10
Patch Changes
- #577
a56898cThanks @whoiskatrin! - Improve backup restores by mounting backup archives from R2 during restore
instead of downloading them into local container storage first.
@cloudflare/sandbox@0.8.9
Patch Changes
-
#570
8363119Thanks @aron-cf! - FixunmountBucket()silently succeeding when the FUSE filesystem fails to unmount. The method now checks thefusermountexit code and throwsBucketUnmountErroron failure, cleans up the mount directory after a successful unmount, and the container image includes the/etc/mtabsymlink thatfusermountrequires. -
#573
cc14fc7Thanks @whoiskatrin! - Increase the defaultgitCheckout()clone timeout to 10 minutes so larger repositories and slower Git remotes do not fail after 2 minutes by default.
You can now override the git clone subprocess timeout per call with thecloneTimeoutMsoption when a checkout needs more time.
@cloudflare/sandbox@0.8.8
Patch Changes
- #571
c5db840Thanks @whoiskatrin! - Require@cloudflare/containers0.3.0 so sandbox apps pick up the latest Containers platform updates.
@cloudflare/sandbox@0.8.7
Patch Changes
@cloudflare/sandbox@0.8.6
Patch Changes
-
#557
f17045bThanks @AshishKumar4! - Fix startup deadlock when using WebSocket transport.Sandboxes that call
exec()or other SDK methods insideonStart()could
get stuck in an infinite timeout loop, requiring a restart. This is now
handled automatically.