Remove SDK-side defaults from API request payloads - #1749
Remove SDK-side defaults from API request payloads#1749devin-ai-integration[bot] wants to merge 10 commits into
Conversation
Co-Authored-By: mish@e2b.dev <mish@e2b.dev>
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
|
Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits. |
🦋 Changeset detectedLatest commit: e9963a5 The changes in this PR will be included in the next version bump. This PR includes changesets to release 2 packages
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 |
Package ArtifactsBuilt from c238c11. Download artifacts from this workflow run. JS SDK ( npm install ./e2b-2.45.1-devin-1787318715-remove-sdk-defaults.0.tgzCLI ( npm install ./e2b-cli-2.17.2-devin-1787318715-remove-sdk-defaults.0.tgzPython SDK ( pip install ./e2b-2.45.1+devin.1787318715.remove.sdk.defaults-py3-none-any.whl |
There was a problem hiding this comment.
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_connectstill applies the SDK-side 300 s default (apiOpts?.timeoutMs ?? DEFAULT_SANDBOX_TIMEOUT_MSinsandboxApi.ts,timeout or SandboxBase.default_sandbox_timeoutin both Pythonsandbox_api.py). After this PRcreate/forkdefer to the API whileconnectdoes not, so the sametimeoutknob has two different "unset" behaviours. Either moveconnectover 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
@defaulttag 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.
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>
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>
…oxy input" This reverts commit b984e34.
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>
|
check comments |
…out default, simplify order docs 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>
| allow_internet_access: opts?.allowInternetAccess ?? true, | ||
| timeout: | ||
| timeoutMs === undefined ? undefined : timeoutToSeconds(timeoutMs), | ||
| secure: opts?.secure, |
There was a problem hiding this comment.
🔒 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.
Reviewed by Cursor Security Reviewer for commit e9963a5. Configure here.


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(wastrue),allow_internet_accessPOST /sandboxes/{id}/connect:timeout(was 300s)POST /sandboxes/{id}/fork:timeout(was 300s),count(was1)POST /sandboxes/{id}/pause:memory(wastrue)cpuCount/memoryMB(were 2 / 1024)Per updated TASTE T-52 (client validation must not mirror backend business rules), the client-side fork
count >= 1pre-validation is also removed — an invalid count now surfaces as the API's own 400 error instead of a client-sideInvalidArgumentError/InvalidArgumentException.The generated clients still mark connect
timeoutas required (spec is pinned pre-API-change), so the omission is done at the call site: a cast in JS, and a smallConnectSandboxBodysubclass in Python that dropstimeoutfromto_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
securecreates unsecured sandboxes and omitting connecttimeoutis 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, andpackages/python-sdk/tests/shared/{sandbox,template}/test_api_defaults.py.Usage stays the same; only the outgoing payloads change:
Linear: SDK-346
Link to Devin session: https://app.devin.ai/sessions/1921bb3818604f3a95b0db1272cff3cd
Requested by: @mishushakov