You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When a command stream (Process.Start, most visibly commands.run) is cancelled from the client side, there is no shared identifier to join the client-side reason with the server-side (envd) log line. Operators can only correlate by sandbox id + timestamp, which is ambiguous under concurrency.
This is the client-side half of the observability gap that the server-side change e2b-dev/runtime#3647 starts to address.
Background
envd runs the guest process on a context decoupled from the streaming RPC (context.Background()-derived), so cancelling the stream does not kill the process — it runs to completion. A client that stops reading the stream (request timeout, a sibling task cancelling, the caller exiting, or an explicit disconnect()) therefore produces, on the server:
Process start (server stream end) error="context canceled" error_code=... operation_id=17
Client (SDK):CommandHandle (_handle_events / wait / disconnect) logs nothing when the stream is cancelled or disconnected, even though the SDK already carries a logging.Logger via ConnectionConfig. And disconnect() explicitly stops reading without killing the process — exactly the "process exited 0 but no result was collected" case — with no client-side trace.
The correlation gap
The operation_id in envd logs is assigned server-side (AssignOperationID, a monotonic counter). The client never sees it.
envd does not read any client-supplied request/correlation header (AddRequestIDToContext only assigns its own).
So there is no id today that appears in both the SDK logs and the envd logs. Joining them requires one.
Proposal
SDK generates a per-call correlation id and sends it as a request header (e.g. X-E2B-Request-Id) on the streaming RPCs.
envd reads that header (falling back to its own assigned id when absent) and includes it in the stream log lines alongside operation_id.
SDK logs the local cancel cause (timeout / sibling-cancel / caller-exit / explicit disconnect / RPC error) via the existing ConnectionConfig.logger, tagged with the same correlation id.
Result: the envd "server stream end" line and the SDK cancel log become joinable by id, and each line carries the half of the story the other side cannot see.
Scope / rollout
Cross-repo: SDK (this repo, e2b-dev/E2B) + envd (e2b-dev/runtime). Backward compatible — envd falls back to its own id when the header is absent, so older SDKs keep working.
Can land incrementally: (a) SDK-side cancel-cause logging alone is already useful (correlate by sandbox id + timestamp); (b) the shared header closes the loop.
Opening this to align on the header name and direction before implementing. Related server-side work: e2b-dev/runtime#3647.
Summary
When a command stream (
Process.Start, most visiblycommands.run) is cancelled from the client side, there is no shared identifier to join the client-side reason with the server-side (envd) log line. Operators can only correlate by sandbox id + timestamp, which is ambiguous under concurrency.This is the client-side half of the observability gap that the server-side change e2b-dev/runtime#3647 starts to address.
Background
envd runs the guest process on a context decoupled from the streaming RPC (
context.Background()-derived), so cancelling the stream does not kill the process — it runs to completion. A client that stops reading the stream (request timeout, a sibling task cancelling, the caller exiting, or an explicitdisconnect()) therefore produces, on the server:Two problems, one on each side:
CommandHandle(_handle_events/wait/disconnect) logs nothing when the stream is cancelled or disconnected, even though the SDK already carries alogging.LoggerviaConnectionConfig. Anddisconnect()explicitly stops reading without killing the process — exactly the "process exited 0 but no result was collected" case — with no client-side trace.The correlation gap
operation_idin envd logs is assigned server-side (AssignOperationID, a monotonic counter). The client never sees it.AddRequestIDToContextonly assigns its own).So there is no id today that appears in both the SDK logs and the envd logs. Joining them requires one.
Proposal
X-E2B-Request-Id) on the streaming RPCs.operation_id.disconnect/ RPC error) via the existingConnectionConfig.logger, tagged with the same correlation id.Result: the envd "server stream end" line and the SDK cancel log become joinable by id, and each line carries the half of the story the other side cannot see.
Scope / rollout
e2b-dev/E2B) + envd (e2b-dev/runtime). Backward compatible — envd falls back to its own id when the header is absent, so older SDKs keep working.Opening this to align on the header name and direction before implementing. Related server-side work: e2b-dev/runtime#3647.