Skip to content

chore: bump e2b to 2.38.3 (JS) / 2.38.0 (Python), fix HTTP/1.1 transport - #328

Open
mishushakov wants to merge 2 commits into
mainfrom
bump-e2b-version-changeset
Open

chore: bump e2b to 2.38.3 (JS) / 2.38.0 (Python), fix HTTP/1.1 transport#328
mishushakov wants to merge 2 commits into
mainfrom
bump-e2b-version-changeset

Conversation

@mishushakov

@mishushakov mishushakov commented Aug 11, 2026

Copy link
Copy Markdown
Member

Bumps e2b in both packages — JS ^2.28.0^2.38.3 and Python ^2.26.0^2.38.0 — with both lockfiles regenerated and a patch changeset added.

The Python bump is a breaking one for us: e2b 2.38.0 moved the SDK's HTTP stack onto pyqwest and the internal e2b.api.client_{sync,async}.get_transport() no longer accepts http2, so our get_transport(config, http2=False) raised TypeError on every _client access and broke all Jupyter traffic. Dropping the argument alone would have been a silent regression instead, since the shared transport lets ALPN negotiate HTTP/2 against the sandbox, where a cancelled request only resets the stream and the server never receives the http.disconnect the template relies on to interrupt the kernel. Jupyter requests therefore build their own transport now, in python/e2b_code_interpreter/transport.py, with http_version pinned to HTTP/1.1 and the SDK's pool tuning and connect-only retry policy reused.

Verified locally: the pyqwest.access log confirms our transport negotiates HTTP/1.1 where the SDK's shared one negotiates HTTP/2, both _client properties construct, ruff check/format and the offline tests/test_sandbox_url.py pass, all 137 Python tests collect, and tsc --noEmit passes on the JS package — which reaches Jupyter through global fetch rather than the SDK's dispatchers and so needed no change. The integration suites that actually exercise disconnect-driven cancellation need a live API key and are left to CI.

🤖 Generated with Claude Code

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@cla-bot cla-bot Bot added the cla-signed label Aug 11, 2026
@cursor

cursor Bot commented Aug 11, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
Python Jupyter traffic now goes through custom pyqwest HTTP/1.1 transports instead of the SDK default ALPN stack, which affects streaming execution and cancellation behavior.

Overview
JavaScript e2b is raised to ^2.38.3 with pnpm-lock.yaml updated. Python e2b is raised to ^2.38.0 with poetry.lock picking up the SDK’s pyqwest / connectrpc stack.

Sync and async Jupyter clients no longer call the SDK get_transport(..., http2=False) because that option is gone. They use new e2b_code_interpreter.transport helpers that build cached HTTP/1.1 pyqwest transports with the same pool and connect-retry settings as the SDK, so streaming /execute still sees client disconnects as TCP closes and can cancel long runs. A patch changeset covers both packages.

Reviewed by Cursor Bugbot for commit d268be9. Bugbot is set up for automated code reviews on this repo. Configure here.

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This is a version-bump PR, but it breaks the Python SDK: e2b 2.38.0 changed get_transport() to no longer accept the http2 kwarg, and both code_interpreter_sync.py and code_interpreter_async.py still pass http2=False. That will raise a TypeError on first use of _client in every sync/async sandbox call, so this needs a fix before merging (see inline comment).

Extended reasoning...

Verified directly against the actual e2b 2.38.0 wheel: both e2b/api/client_sync/__init__.py and e2b/api/client_async/__init__.py define get_transport(config) with a single positional parameter and no **kwargs. This repo's code_interpreter_sync.py:84 and code_interpreter_async.py:89 call get_transport(self.connection_config, http2=False), which will raise TypeError: get_transport() got an unexpected keyword argument 'http2' the first time _client is accessed — i.e., on essentially every run_code/context call in both sandbox flavors. This is a real, high-severity regression introduced by the dependency bump (the PR itself only touches lockfiles/manifests, but the new pinned version is incompatible with existing call sites), not a false positive from the finder agents. Deferring rather than approving.

Comment thread python/pyproject.toml
e2b 2.38.0 moved the Python SDK's HTTP stack onto pyqwest, dropping the
`http2` argument from the internal `get_transport()` helper. Passing it
raised `TypeError` on every `_client` access, and simply dropping it would
have left Jupyter requests on ALPN-negotiated HTTP/2, where a cancelled
request only resets the stream and the server never sees the disconnect.

Build the transport in `e2b_code_interpreter.transport` instead, with
`http_version` pinned to HTTP/1.1 and the SDK's pool tuning and
connect-only retry policy, so client disconnects still arrive as a TCP
close and long-running executions stay cancellable.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@mishushakov mishushakov changed the title chore: bump e2b to 2.38.3 (JS) and 2.38.0 (Python) chore: bump e2b to 2.38.3 (JS) / 2.38.0 (Python), fix HTTP/1.1 transport Aug 12, 2026
@mishushakov
mishushakov enabled auto-merge (squash) August 12, 2026 16:45
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