Sandbox ID or Build ID
No response
Environment
e2b==2.8.1
python-sdk
Timestamp of the issue
2026-02-11 15:00 PST
Frequency
One-time occurrence
Expected behavior
if sandbox is unreachable, commands.run should error out
Actual behavior
if sandbox is unreachable, commands.run hangs forever
Issue reproduction
- Create a sandbox and run some commands successfully
- Wait for the sandbox to become unreachable (e.g., sandbox times out or dies)
- Call commands.run() — it hangs indefinitely because there is no read timeout on the HTTP stream
Additional context
There was a blip in e2b of some sort and we saw couple of our sandboxes die or timeout at the same time that a long running command had been issued; the command was retried automatically with the commands.run, but then all of those tasks in our system hung indefinitely getting stuck at commands.run.
My (claude's) best guess:
When a sandbox becomes unreachable (e.g., sandbox dies or network connectivity is lost), commands.run() hangs indefinitely because the underlying call_server_stream does not set a read timeout on the HTTP stream. The request_timeout parameter only sets connect and pool timeouts for streaming calls, unlike unary calls which correctly set all four (connect, pool, read, write).
In e2b_connect/client.py, _prepare_unary_request (used by files.make_dir, files.write, etc.) correctly sets all timeouts:
extensions = {
"timeout": {
"connect": request_timeout,
"pool": request_timeout,
"read": request_timeout,
"write": request_timeout,
}
}
But _prepare_server_stream_request (used by commands.run) omits read and write:
extensions = {
"timeout": {"connect": request_timeout, "pool": request_timeout}
}
The timeout parameter is sent as a connect-timeout-ms header for server-side enforcement, but if the server is unreachable, the client never gets a response and httpcore's ConnectionPool.stream() blocks on read forever.
Sandbox ID or Build ID
No response
Environment
e2b==2.8.1
python-sdk
Timestamp of the issue
2026-02-11 15:00 PST
Frequency
One-time occurrence
Expected behavior
if sandbox is unreachable, commands.run should error out
Actual behavior
if sandbox is unreachable, commands.run hangs forever
Issue reproduction
Additional context
There was a blip in e2b of some sort and we saw couple of our sandboxes die or timeout at the same time that a long running command had been issued; the command was retried automatically with the commands.run, but then all of those tasks in our system hung indefinitely getting stuck at
commands.run.My (claude's) best guess:
When a sandbox becomes unreachable (e.g., sandbox dies or network connectivity is lost), commands.run() hangs indefinitely because the underlying call_server_stream does not set a read timeout on the HTTP stream. The request_timeout parameter only sets connect and pool timeouts for streaming calls, unlike unary calls which correctly set all four (connect, pool, read, write).
In e2b_connect/client.py, _prepare_unary_request (used by files.make_dir, files.write, etc.) correctly sets all timeouts:
But _prepare_server_stream_request (used by commands.run) omits read and write:
The timeout parameter is sent as a connect-timeout-ms header for server-side enforcement, but if the server is unreachable, the client never gets a response and httpcore's ConnectionPool.stream() blocks on read forever.