diff --git a/docs/sandbox.mdx b/docs/sandbox.mdx
index 6c37ccd3..301d4b74 100644
--- a/docs/sandbox.mdx
+++ b/docs/sandbox.mdx
@@ -134,3 +134,5 @@ sandbox = Sandbox.create(timeout=60)
sandbox.kill()
```
+
+For details on how the SDK handles operations during state transitions (pause, resume, kill) and a reference of possible errors, see [Behavior during state transitions](/docs/sandbox/persistence#behavior-during-state-transitions).
diff --git a/docs/sandbox/auto-resume.mdx b/docs/sandbox/auto-resume.mdx
index 06d04e33..a734bb92 100644
--- a/docs/sandbox/auto-resume.mdx
+++ b/docs/sandbox/auto-resume.mdx
@@ -66,6 +66,8 @@ That includes SDK operations like:
If a sandbox is paused and `autoResume` is enabled, the next supported operation resumes it automatically. You do not need to call [`Sandbox.connect()`](/docs/sandbox/connect) first.
+When auto-resume triggers, the SDK handles the resume transparently — if the sandbox is mid-transition, operations wait for the transition to complete. See [Behavior during state transitions](/docs/sandbox/persistence#behavior-during-state-transitions) for the full error reference.
+
### SDK example: pause, then read a file
diff --git a/docs/sandbox/connect.mdx b/docs/sandbox/connect.mdx
index e62977e4..63baae49 100644
--- a/docs/sandbox/connect.mdx
+++ b/docs/sandbox/connect.mdx
@@ -74,3 +74,5 @@ r = sandbox.commands.run("whoami")
print(f"Running in sandbox {sandbox.sandbox_id} as \"{r.stdout.strip()}\"")
```
+
+If the sandbox is paused, `Sandbox.connect()` automatically resumes it before returning. If the sandbox is mid-transition (for example, currently pausing), the SDK waits for the transition to complete. See [Behavior during state transitions](/docs/sandbox/persistence#behavior-during-state-transitions) for details and error handling.
diff --git a/docs/sandbox/persistence.mdx b/docs/sandbox/persistence.mdx
index 3042df07..f5ab1634 100644
--- a/docs/sandbox/persistence.mdx
+++ b/docs/sandbox/persistence.mdx
@@ -69,6 +69,81 @@ sandbox.kill() # Running/Paused → Killed
```
+## Behavior during state transitions
+
+Lifecycle operations like `pause()`, `connect()`, and `kill()` can take a variable amount of time to complete — pausing, for example, takes approximately 4 seconds per GiB of RAM. If you call an SDK operation while a sandbox is mid-transition, the SDK automatically waits for the transition to finish and then executes your operation. From your code's perspective, the transition appears instant.
+
+
+You do not need to poll sandbox state or add retry logic around transitions. The SDK handles waiting for you.
+
+
+Here's what happens in specific scenarios:
+
+| Scenario | What the SDK does |
+|---|---|
+| Call `commands.run()` while sandbox is pausing | Waits for pause to complete, then resumes the sandbox, then runs the command |
+| Call `connect()` on a paused sandbox | Automatically resumes the sandbox and returns a connected instance |
+| Call `connect()` on an already-running sandbox | Connects immediately — no state change needed |
+| Call `kill()` from any state | Transitions the sandbox to Killed, regardless of current state |
+| Call `pause()` on an already-paused sandbox | Returns immediately — no-op |
+
+### Errors during lifecycle operations
+
+When a lifecycle operation fails, the SDK raises one of the following errors. This table covers the most common cases — see the full error reference for [JavaScript](/docs/sdk-reference/js-sdk/v2.14.1/errors) and [Python](/docs/sdk-reference/python-sdk/v2.9.1/exceptions).
+
+| Operation | Error (JS / Python) | When it occurs |
+|---|---|---|
+| `pause()` | `NotFoundError` / `NotFoundException` | Sandbox doesn't exist or was already killed |
+| `connect()` | `NotFoundError` / `NotFoundException` | Sandbox ID doesn't exist |
+| `connect()` | `TimeoutError` / `TimeoutException` | Resume didn't complete within the timeout window |
+| `kill()` | `NotFoundError` / `NotFoundException` | Sandbox doesn't exist |
+| Any operation during a transition | `TimeoutError` / `TimeoutException` | The transition plus the operation together exceeded the request timeout |
+
+Here's an example of handling errors during lifecycle operations:
+
+
+```js JavaScript & TypeScript
+import { Sandbox, TimeoutError, NotFoundError } from '@e2b/code-interpreter'
+
+const sbx = await Sandbox.create()
+const sandboxId = sbx.sandboxId
+
+await sbx.pause()
+
+try {
+ // connect() automatically resumes a paused sandbox
+ const resumed = await Sandbox.connect(sandboxId)
+ const result = await resumed.commands.run('echo hello')
+ console.log(result.stdout)
+} catch (error) {
+ if (error instanceof NotFoundError) {
+ console.error('Sandbox no longer exists:', error.message)
+ } else if (error instanceof TimeoutError) {
+ console.error('Operation timed out during transition:', error.message)
+ }
+}
+```
+```python Python
+from e2b_code_interpreter import Sandbox
+from e2b import TimeoutException, NotFoundException
+
+sbx = Sandbox.create()
+sandbox_id = sbx.sandbox_id
+
+sbx.pause()
+
+try:
+ # connect() automatically resumes a paused sandbox
+ resumed = Sandbox.connect(sandbox_id)
+ result = resumed.commands.run("echo hello")
+ print(result.stdout)
+except NotFoundException as e:
+ print(f"Sandbox no longer exists: {e}")
+except TimeoutException as e:
+ print(f"Operation timed out during transition: {e}")
+```
+
+
## Pausing sandbox
When you pause a sandbox, both the sandbox's filesystem and memory state will be saved. This includes all the files in the sandbox's filesystem and all the running processes, loaded variables, data, etc.