fix: update pause() JSDoc and add apiKey propagation regression test#1224
fix: update pause() JSDoc and add apiKey propagation regression test#1224passionworkeer wants to merge 3 commits intoe2b-dev:mainfrom
Conversation
When a sandbox becomes unreachable, commands.run() hangs indefinitely because the underlying httpx stream does not have read/write timeouts set. The _prepare_server_stream_request method only set connect and pool timeouts, but omitted read and write timeouts. This is inconsistent with _prepare_unary_request which correctly sets all four timeouts. This fix adds read and write timeouts to server stream requests, ensuring that commands.run() respects the request_timeout parameter even when the sandbox becomes unreachable. Closes e2b-dev#1128 Signed-off-by: passionworkeer <passionworkeer@users.noreply.github.com>
- JSDoc for pause() incorrectly said it returns sandbox ID; now correctly says it returns boolean (true=paused, false=already paused) - Add regression test: connect with explicit apiKey, unset E2B_API_KEY env, call pause() and verify it succeeds without needing env var
|
There was a problem hiding this comment.
Pull request overview
This PR aims to correct the JS SDK pause() documentation to match its actual boolean return value and adds a regression test ensuring Sandbox.connect() credentials (apiKey) are usable by subsequent pause() calls when E2B_API_KEY is unset. It also includes an unrelated Python SDK change adjusting stream request timeout extensions.
Changes:
- Update
Sandbox.pause()JSDoc to document a boolean return (truepaused,falsealready paused). - Add a JS integration test verifying
connect()+pause()succeeds withoutE2B_API_KEYwhen an explicitapiKeyis provided. - Expand Python SDK server-stream request timeout extensions to include
read/writetimeouts.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
| packages/python-sdk/e2b_connect/client.py | Adds read/write to timeout extensions for server-stream requests (scope not reflected in PR description). |
| packages/js-sdk/tests/sandbox/connect.test.ts | Adds regression test for apiKey propagation from connect() to pause() when env var is unset. |
| packages/js-sdk/src/sandbox/index.ts | Updates pause() JSDoc return description to boolean semantics. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| * Pause a sandbox by its ID. | ||
| * | ||
| * @param opts connection options. | ||
| * | ||
| * @returns sandbox ID that can be used to resume the sandbox. | ||
| * @returns `true` if the sandbox got paused, `false` if the sandbox was already paused. |
There was a problem hiding this comment.
Sandbox.pause() still forwards only opts to SandboxApi.pause() and does not merge this.connectionConfig (unlike kill()/setTimeout()). As a result, a sandbox created/connected with an explicit apiKey will lose that credential when calling pause() without opts (exactly the regression this PR is testing). Update pause() (and betaPause()) to pass { ...this.connectionConfig, ...opts } so the connected sandbox's apiKey is propagated.
| // Save the original env var (may be undefined, empty string, or set) | ||
| const savedApiKey = process.env.E2B_API_KEY | ||
|
|
||
| try { | ||
| // Ensure E2B_API_KEY is not set for this test | ||
| delete process.env.E2B_API_KEY | ||
|
|
||
| // Connect with explicit apiKey (from the created sandbox's credentials) | ||
| const connected = await Sandbox.connect(sandbox.sandboxId, { | ||
| apiKey: savedApiKey, | ||
| }) |
There was a problem hiding this comment.
This test can become flaky or fail locally because it passes apiKey: savedApiKey even when process.env.E2B_API_KEY is undefined/empty. In that case Sandbox.connect will be called without a valid API key (and the env var is deleted), so the test doesn't actually exercise the intended scenario. Add a guard to skip/fail fast when savedApiKey is not a non-empty string, or obtain a known-valid apiKey from test config/fixtures instead of reading the env var opportunistically.
| // Ensure E2B_API_KEY is not set for this test | ||
| delete process.env.E2B_API_KEY | ||
|
|
||
| // Connect with explicit apiKey (from the created sandbox's credentials) |
There was a problem hiding this comment.
The comment says the apiKey comes "from the created sandbox's credentials", but the code uses process.env.E2B_API_KEY. Please update the comment to reflect the actual source of the key to avoid confusion when maintaining this test.
| // Connect with explicit apiKey (from the created sandbox's credentials) | |
| // Connect with explicit apiKey taken from the original E2B_API_KEY env var |
| "read": request_timeout, | ||
| "write": request_timeout, |
There was a problem hiding this comment.
Setting server-stream read/write timeouts to request_timeout changes streaming semantics: callers use timeout to control how long the stream should stay open (including 0 for unlimited), but a small request_timeout will now terminate an otherwise-valid long-lived stream due to read inactivity (even though keepalive pings are configured at 50s elsewhere). Consider leaving read/write unset for server streams, or deriving them from the stream timeout/keepalive interval (and documenting the behavior) so long-lived streams aren't unintentionally cut off.
| "read": request_timeout, | |
| "write": request_timeout, |
| extensions = ( | ||
| None | ||
| if request_timeout is None | ||
| else {"timeout": {"connect": request_timeout, "pool": request_timeout}} | ||
| else { | ||
| "timeout": { | ||
| "connect": request_timeout, | ||
| "pool": request_timeout, | ||
| "read": request_timeout, | ||
| "write": request_timeout, | ||
| } | ||
| } |
There was a problem hiding this comment.
This PR is described as a JS pause() JSDoc fix + JS regression test, but this hunk also changes Python SDK transport timeouts. If this is intentional, it should be called out in the PR description; otherwise, consider moving it to a separate PR to keep scope focused and reduce review/rollback risk.
Co-Authored-By: copilot-pullrequestreviewer[bot] <55177212+copilot-pullrequestreviewer[bot]@users.noreply.github.com>
… comment Address Copilot review feedback on PR e2b-dev#1224: 1. Skip the test when E2B_API_KEY is not set - avoids calling Sandbox.connect with undefined apiKey (test flakiness fix) 2. Fix misleading comment: apiKey comes from E2B_API_KEY env var, not from the created sandbox's credentials
Fix Copilot review feedback on PR #1218:
JSDoc fix: pause() method JSDoc incorrectly said it returns sandbox ID; now correctly says it returns boolean (true=paused, false=already paused)
Regression test: Added test that verifies connect() properly propagates apiKey to pause() - when E2B_API_KEY env is unset, calling pause() on a connected sandbox with explicit apiKey succeeds.
Closes #1218
@copilot