Skip to content

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

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

Remove SDK-side defaults from API request payloads#1749
devin-ai-integration[bot] wants to merge 10 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:

  • POST /sandboxes: timeout (was 300s), secure (was true), allow_internet_access
  • POST /sandboxes/{id}/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

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.

The generated clients still mark connect timeout as required (spec is pinned pre-API-change), so the omission is done at the call site: a cast in JS, and a small ConnectSandboxBody subclass in Python that drops timeout from to_dict() when unset. These can be removed once the spec pin is bumped after the API-side default lands.

Note (intentionally breaking until the API changes deploy): with this PR, omitting secure creates unsecured sandboxes and omitting connect timeout is rejected by the current API. API-side defaults are in belt PRs #2057 (secure by default) and #2059 (connect default timeout).

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.

Usage stays the same; only the outgoing payloads change:

await Sandbox.create('base')                       // no timeout/secure/allow_internet_access sent
await Sandbox.connect(id)                          // no timeout sent
await Sandbox.connect(id, { timeoutMs: 60_000 })   // timeout: 60

Linear: SDK-346

Link to Devin session: https://app.devin.ai/sessions/1921bb3818604f3a95b0db1272cff3cd
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: e9963a5

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

This PR includes changesets to release 2 packages
Name Type
e2b Minor
@e2b/python-sdk 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 c238c11. Download artifacts from this workflow run.

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

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

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

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

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

pip install ./e2b-2.45.1+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
Co-Authored-By: mish@e2b.dev <mish@e2b.dev>
allow_internet_access: opts?.allowInternetAccess ?? true,
timeout:
timeoutMs === undefined ? undefined : timeoutToSeconds(timeoutMs),
secure: opts?.secure,

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.

🔒 Agentic Security Review
Severity: HIGH

The SDK now omits secure unless callers set it explicitly (secure: opts?.secure), which removes the prior secure-by-default behavior at sandbox creation.

Impact: Callers that rely on defaults can unintentionally create sandboxes with weaker controller access protection while backend defaulting is not universally guaranteed, allowing unauthorized controller interaction when the endpoint is reachable.

Fix in Cursor Fix in Web

Reviewed by Cursor Security Reviewer for commit e9963a5. Configure here.

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