Skip to content

fix(sandbox-e2b): reliable exec timeout with server-side kill - #2976

Open
chcodex wants to merge 1 commit into
agentscope-ai:mainfrom
chcodex:fix/e2b-exec-timeout
Open

fix(sandbox-e2b): reliable exec timeout with server-side kill#2976
chcodex wants to merge 1 commit into
agentscope-ai:mainfrom
chcodex:fix/e2b-exec-timeout

Conversation

@chcodex

@chcodex chcodex commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Fixes #2974.

  • Per-call client disables the idle read timeout (readTimeout=0) so total-duration semantics is owned solely by callTimeout; previously a small base readTimeout preempted callTimeout and misreported a short idle stall as a full exec timeout (both surface as InterruptedIOException).
  • Send Connect-Timeout-Ms so envd kills the remote process server-side; previously a client timeout only dropped our HTTP stream and leaked the process.
  • External cancellation (Thread.interrupt()) is rethrown as-is with the interrupt bit restored instead of being wrapped as ExecTimeoutException.
  • timeoutSeconds <= 0 now fails fast with IllegalArgumentException.
  • Tests: E2bEnvdProcessClientTest 10/10 pass (4 new: header carried end-to-end, interruption rethrown with bit restored, fail-fast without request; plus existing codec/drain cases). Full reactor test BUILD SUCCESS.

@chcodex
chcodex force-pushed the fix/e2b-exec-timeout branch from 75090ec to b64ed41 Compare September 4, 2026 03:48
@codecov

codecov Bot commented Sep 4, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 84.61538% with 2 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...e/extensions/sandbox/e2b/E2bEnvdProcessClient.java 84.61% 1 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

@CryoThrust CryoThrust 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.

One small robustness concern: res.body().string() is now unconditional in the non-success response path. OkHttp permits a response with a null body (for example a 204/transport edge or a test double), so this can replace the intended SandboxRuntimeException with an NPE. Keeping the previous null-safe fallback (res.body() != null ? res.body().string() : "") would preserve the error contract while still including the server body when present. A regression test with a non-success response and no body would pin this.

@chcodex

chcodex commented Sep 4, 2026

Copy link
Copy Markdown
Contributor Author

@CryoThrust Thanks for flagging this. The null guard was removed deliberately:

  • Response.body is a non-null contract in OkHttp (Kotlin val body: ResponseBody). For a real Call.execute() response — the only path that reaches this code — an empty body (204/304, truncated gateway reply) arrives as EmptyResponseBody, so .string() returns "" rather than throwing NPE.
  • A null body can only come from a hand-built Response.Builder.build() without setting a body, which cannot occur on this production path. IDEA's nullability inference (from OkHttp's annotations) agrees and reports res.body() != null as always-true, i.e. the guard is dead code.
  • The suggested regression test (non-success response with no body) would only exercise such a hand-built double, not a real server reply, so it would pin behavior that cannot happen in production.

chcodex added a commit to chcodex/agentscope-java that referenced this pull request Sep 4, 2026
- agentscope-ai#2196: pass username query param in e2b filesystem REST calls
  (filesUrl helper plus URL assertions and workspace state setup)
- agentscope-ai#2555: drop dead snapshot-timestamp helpers from E2bPlatformHttp,
  restore coverage tests plus InputStream close fix
- agentscope-ai#2976: reliable e2b exec timeout with server-side kill
  (callTimeout plus readTimeout(0), Connect-Timeout-Ms header,
  interrupt-bit handling) plus its tests
- E2bEnvdProcessClientTest: align three stale drain tests with the
  merged upstream agentscope-ai#2828 reject-without-exit-code behavior
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[sandbox-e2b] exec timeout is unreliable: readTimeout preempts callTimeout, no server-side kill, cancellation misreported

2 participants