Skip to content

Remove SDK-side defaults from API request payloads - #1749

Open
devin-ai-integration[bot] wants to merge 22 commits into
mainfrom
devin/1787318715-remove-sdk-defaults
Open

devin-ai-integration[bot] wants to merge 22 commits into
mainfrom
devin/1787318715-remove-sdk-defaults

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

Summary

Remove SDK-side defaults from API request payloads (JS + Python sync/async) so omitted options are absent from requests and the API defaults apply. Explicit values — including false/0 — are still serialized unchanged.

Fields no longer preset when omitted:

  • sandbox create: timeout (was 300s), secure (was true), allow_internet_access
  • sandbox connect: timeout (was 300s)
  • POST /sandboxes/{id}/fork: timeout (was 300s), count (was 1)
  • POST /sandboxes/{id}/pause: memory (was true)
  • template builds: cpuCount/memoryMB (were 2 / 1024)
- secure: opts?.secure ?? true,
+ secure: opts?.secure,

- const timeoutMs = apiOpts?.timeoutMs ?? this.defaultSandboxTimeoutMs  // connect
+ const timeoutMs = apiOpts?.timeoutMs

Create/connect now use the v2 endpoints from belt #3425 (spec/openapi.yml synced via the spec/runtime-ref pin; JS + Python clients regenerated with the pinned generators):

- POST /sandboxes                      body: NewSandbox
+ POST /v2/sandboxes                   body: NewSandboxV2   // no `secure` field, envd always secured, timeout defaults to 300s
- POST /sandboxes/{id}/connect         body: ConnectSandbox   (timeout required)
+ POST /v2/sandboxes/{id}/connect      body: ConnectSandboxV2 (timeout optional, defaults to 300s)

Consequently the secure option on Sandbox.create is deprecated: it stays in the signature (JS SandboxOpts.secure, Python/desktop secure=) so existing callers keep working, but it is ignored — every sandbox is secured, so the SDK has nothing to send. Downstream packages follow: e2b-desktop (Python) no longer presets allow_internet_access=True; the code-interpreter test fixtures stop passing secure. The Python ConnectSandboxBody shim and the JS cast that worked around the required v1 connect timeout are gone too — the generated v2 models already make it optional.

Template.getBuildStatus / Template.get_build_status also stop presetting logsOffset: 0 — omitted, the query param is left out and the API default applies.

Per updated TASTE T-52 (client validation must not mirror backend business rules), the client-side fork count >= 1 pre-validation is also removed — an invalid count now surfaces as the API's own 400 error instead of a client-side InvalidArgumentError/InvalidArgumentException.

Belt #3425 is merged and exported: spec/runtime-ref is bumped to the runtime commit carrying the v2 routes, and make codegen at that pin reproduces the tracked spec and generated clients byte-for-byte. The live integration suites stay red until the API deploy with the v2 routes reaches staging/production (they 404 on /v2/sandboxes until then).

Exact-request tests added/updated in packages/js-sdk/tests/sandbox/apiDefaults.test.ts, packages/js-sdk/tests/template/apiDefaults.test.ts, and packages/python-sdk/tests/shared/{sandbox,template}/test_api_defaults.py; the msw/monkeypatch-mocked suites now intercept the v2 routes.

Usage stays the same; only the outgoing payloads/routes change:

await Sandbox.create('base')                       // POST /v2/sandboxes, no timeout/allow_internet_access sent
await Sandbox.connect(id)                          // POST /v2/sandboxes/{id}/connect, no timeout sent
await Sandbox.connect(id, { timeoutMs: 60_000 })   // timeout: 60
await Sandbox.create('base', { secure: true })     // accepted (deprecated), nothing sent

Linear: SDK-346

Link to Devin session: https://app.devin.ai/sessions/1921bb3818604f3a95b0db1272cff3cd
Open in Devin Desktop: https://app.devin.ai/desktop/session/1921bb3818604f3a95b0db1272cff3cd?variant=devin
Requested by: @mishushakov

Co-Authored-By: mish@e2b.dev <mish@e2b.dev>
@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.
Credits must be used to enable repository wide code reviews.

@cla-bot cla-bot Bot added the cla-signed label Aug 21, 2026
@changeset-bot

changeset-bot Bot commented Aug 21, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: e7306ec

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 3 packages
Name Type
e2b Minor
@e2b/python-sdk Minor
@e2b/desktop-python Minor

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

@github-actions

github-actions Bot commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

Package Artifacts

Built from bedb6cb. Download artifacts from this workflow run.

JS SDK (e2b@2.50.1-devin-1787318715-remove-sdk-defaults.0):

npm install ./e2b-2.50.1-devin-1787318715-remove-sdk-defaults.0.tgz

CLI (@e2b/cli@2.19.2-devin-1787318715-remove-sdk-defaults.0):

npm install ./e2b-cli-2.19.2-devin-1787318715-remove-sdk-defaults.0.tgz

Code Interpreter JS SDK (@e2b/code-interpreter@2.8.1-devin-1787318715-remove-sdk-defaults.0):

npm install ./e2b-code-interpreter-2.8.1-devin-1787318715-remove-sdk-defaults.0.tgz

Desktop JS SDK (@e2b/desktop@2.4.1-devin-1787318715-remove-sdk-defaults.0):

npm install ./e2b-desktop-2.4.1-devin-1787318715-remove-sdk-defaults.0.tgz

Python SDK (e2b==2.50.0+devin.1787318715.remove.sdk.defaults):

pip install ./e2b-2.50.0+devin.1787318715.remove.sdk.defaults-py3-none-any.whl

Code Interpreter Python SDK (e2b-code-interpreter==2.10.0+devin.1787318715.remove.sdk.defaults):

pip install ./e2b_code_interpreter-2.10.0+devin.1787318715.remove.sdk.defaults-py3-none-any.whl

Desktop Python SDK (e2b-desktop==2.5.0+devin.1787318715.remove.sdk.defaults):

pip install ./e2b_desktop-2.5.0+devin.1787318715.remove.sdk.defaults-py3-none-any.whl

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TASTE.md review of the SDK-side default removal.

Checked: parity across JS / sync Python / async Python (T-1, T-2), where defaults live and how they are documented (T-47), server-owns-validation (T-52), absence-is-undefined / Optional[...] = None at the boundary (T-20), and docstring/JSDoc completeness (T-69, T-71, T-72).

The mechanics are clean and applied symmetrically across all three surfaces (UNSET in Python, omitted keys in JS), and the new tests pin both the omit and the explicit-value paths. 4 violations flagged inline, all in the documentation and validation edges rather than the payload change itself.

Not tied to a changed line:

  • connect/_cls_connect still applies the SDK-side 300 s default (apiOpts?.timeoutMs ?? DEFAULT_SANDBOX_TIMEOUT_MS in sandboxApi.ts, timeout or SandboxBase.default_sandbox_timeout in both Python sandbox_api.py). After this PR create/fork defer to the API while connect does not, so the same timeout knob has two different "unset" behaviours. Either move connect over too or say in the changeset why it keeps a client default.
  • Several new doc lines restate the server's current value in prose ("currently enabled", "currently allowed", "currently 1", "currently a full memory snapshot"). That is the drift T-47 exists to avoid, without the machine-readable @default tag that made the value greppable. If the value is worth documenting, document it as @default; if it isn't, say only that the SDK omits the field and the API decides.

Comment thread packages/js-sdk/src/sandbox/index.ts
Comment thread packages/js-sdk/src/sandbox/sandboxApi.ts Outdated
Comment thread packages/js-sdk/src/sandbox/sandboxApi.ts Outdated
Comment thread packages/js-sdk/src/sandbox/sandboxApi.ts Outdated
Comment thread packages/python-sdk/e2b/sandbox_sync/sandbox_api.py Outdated
Comment thread packages/js-sdk/src/template/index.ts
devin-ai-integration Bot and others added 2 commits August 21, 2026 14:19
Co-Authored-By: mish@e2b.dev <mish@e2b.dev>
Co-Authored-By: mish@e2b.dev <mish@e2b.dev>
Comment thread packages/js-sdk/src/sandbox/sandboxApi.ts Outdated
devin-ai-integration Bot and others added 2 commits August 21, 2026 14:27
Co-Authored-By: mish@e2b.dev <mish@e2b.dev>
The BYOP surface from #1688 diverged for callers that bypass the types.
Python raised InvalidArgumentException on a proxy without a string
address; JS rebuilt the body from the known fields, so `egressProxy`
passed as a bare string sent `{}` and the caller got an API error naming
a field they never left out. Mirror the guard in buildEgressProxyBody,
the way buildIamBody already does for untyped token maps.

Both SDKs also forwarded a null/None username or password as a JSON
null, which the API rejects — `{"username": os.environ.get(...)}` on an
unset variable is the way that happens. Read it as "no credentials",
the same reading both already gave `egressProxy: null` itself, and
normalize a null username coming back out of getInfo so
SandboxEgressProxyInfo.username cannot be a null its type forbids.

The get_info example published in both CHANGELOGs for 2.41.0 subscripts
`info.network["egress_proxy"]`, which KeyErrors on every sandbox without
a proxy — SandboxNetworkInfo is total=False and the key is only set when
one is configured.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
devin-ai-integration Bot and others added 2 commits August 21, 2026 14:43
Fixture sandboxes previously inherited the SDK's 300s create default;
after removing SDK-side defaults they would fall back to the API's 15s
default, making long-running integration tests flaky.

Co-Authored-By: mish@e2b.dev <mish@e2b.dev>
@mishushakov

Copy link
Copy Markdown
Member

check comments

devin-ai-integration Bot and others added 2 commits August 21, 2026 15:15
…out default, simplify order docs

Co-Authored-By: mish@e2b.dev <mish@e2b.dev>
Co-Authored-By: mish@e2b.dev <mish@e2b.dev>

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale comment

Comment thread packages/js-sdk/src/sandbox/sandboxApi.ts Outdated
Co-Authored-By: mish@e2b.dev <mish@e2b.dev>

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale comment

Comment thread packages/js-sdk/src/sandbox/sandboxApi.ts Outdated
@mishushakov

Copy link
Copy Markdown
Member

resolve conflicts

Co-Authored-By: mish@e2b.dev <mish@e2b.dev>
@linear-code

linear-code Bot commented Sep 9, 2026

Copy link
Copy Markdown

SDK-346

@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

Resolved — merged main (7f20cda). Conflicts were in the connect body (sandboxApi.ts, Python sync/async sandbox_api.py): kept the optional timeout and added main's new memory (onResume) field; ConnectSandboxBody now forwards memory. Format/lint/typecheck + api-defaults tests pass.

Co-Authored-By: mish@e2b.dev <mish@e2b.dev>

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale comment

Security review of this PR found one high-severity issue: removing the SDK secure: true default can create unsecured sandboxes until the API-side default is deployed.

Open in Web View Automation 

Sent by Cursor Security Agent: Security Reviewer

Comment thread packages/js-sdk/src/sandbox/sandboxApi.ts Outdated
devin-ai-integration Bot and others added 5 commits September 16, 2026 12:53
Sync the v2 create/connect routes into spec/openapi.yml and regenerate the
JS and Python API clients. Sandbox.create posts to /v2/sandboxes
(NewSandboxV2, no secure field: envd access is always secured) and
Sandbox.connect posts to /v2/sandboxes/{id}/connect with an optional body,
so omitted timeouts fall back to the API's 300s default. Drops the secure
option from create and the Python ConnectSandboxBody shim.

Co-Authored-By: mish@e2b.dev <mish@e2b.dev>
Co-Authored-By: mish@e2b.dev <mish@e2b.dev>
…tests at v2 create

Co-Authored-By: mish@e2b.dev <mish@e2b.dev>
Co-Authored-By: mish@e2b.dev <mish@e2b.dev>
Comment thread packages/desktop-python/e2b_desktop/main.py
Comment thread packages/js-sdk/src/sandbox/sandboxApi.ts
devin-ai-integration Bot and others added 5 commits September 16, 2026 13:39
secure stays in the create signatures (JS, Python sync/async, desktop-python)
so existing callers don't hit an invalid-argument error, but it is ignored and
never serialized into NewSandboxV2. Template.getBuildStatus no longer presets
logsOffset=0; when omitted the API default applies.

Co-Authored-By: mish@e2b.dev <mish@e2b.dev>
Co-Authored-By: mish@e2b.dev <mish@e2b.dev>
Co-Authored-By: mish@e2b.dev <mish@e2b.dev>
Co-Authored-By: mish@e2b.dev <mish@e2b.dev>
…ct spec

Co-Authored-By: mish@e2b.dev <mish@e2b.dev>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant