Skip to content

[Bug]: commands.run hangs indefinitely when sandbox becomes unreachable — request_timeout does not set read timeout on streaming calls #1128

Description

@simsinght

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

  1. Create a sandbox and run some commands successfully
  2. Wait for the sandbox to become unreachable (e.g., sandbox times out or dies)
  3. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions