#6369·deepagents

fix(code): own sandbox lifetime from the client in non-interactive runs

Author: wei-w-wangCreated Sep 17, 2026Updated Sep 17, 2026
Labelstype:bugpackage:deepagentsorg:externalpriority:backlogpackage:dcodetopic:sandboxes

Submission checklist

  • This is a bug, not a usage question.
  • I added a clear and descriptive title.
  • I searched existing issues and didn't find this.
  • I can reproduce this with the latest released version.
  • I included a minimal reproducible example and steps to reproduce.

Area (Required)

  • deepagents (SDK)
  • dcode
  • talon
  • acp
  • evals
  • daytona
  • modal
  • quickjs
  • runloop
  • vercel
  • langsmith-sandbox
  • Other / not sure / general

Related Issues / PRs

https://github.com/langchain-ai/deepagents/pull/6368

Reproduction Steps / Example Code (Python)

python
E2B is self-hosted on two local servers (control plane and sandbox server). A single non-interactive run leaves its sandbox alive: after dcode exits, the Firecracker microVM is still running on the sandbox server. 

Command to reproduce:

export DEEPAGENTS_CODE_DEBUG=1

export E2B_DOMAIN=e2b.internal
export E2B_API_KEY=xxx
export E2B_API_URL=http://192.168.100.2:3000
export E2B_SANDBOX_URL=http://192.168.100.2:3002

export MODEL_ID=""
export OPENAI_BASE_URL=""
export OPENAI_API_KEY=

dcode \
  --model "openai:${MODEL_ID}" \
  --model-params '{"use_responses_api":false}' \
  --sandbox e2b \
  --no-mcp \
  --shell-allow-list "python,python3" \
  -n "Create hello.py containing print('hello_world') in the sandbox. Execute python3 hello.py in the sandbox and report the actual output."

Error Message and Stack Trace (if applicable)

bash

Description

E2B is self-hosted on two local servers (control plane and sandbox server). A single non-interactive run leaves its sandbox alive: after dcode exits, the Firecracker microVM is still running on the sandbox server. It is destroyed a few minutes later, when the E2B sandbox timeout expires — not by dcode.

Expected: create_sandbox in integrations/sandbox_factory.py deletes the sandbox in its finally block when it created it (should_cleanup = sandbox_id is None), so the sandbox should go away when the run ends.

Actual: the delete is never issued. The sandbox is created in the langgraph server process (server_graph.py), which registers cleanup via atexit. The CLI stops that server with killpg(pgid, SIGTERM) (client/launch/server.py). CPython installs a handler for SIGINT but leaves SIGTERM at SIG_DFL, so the server is terminated by the kernel without running atexit, and provider.delete() never fires. Changing that signal to SIGINT in _terminate_server_process makes the sandbox disappear immediately, which confirms the path. hello-world test command:

Environment / System Info

No response