Skip to content

Environment lifecycle

The task-environment state machine — how a `POST /environments` advances from build → provision → ready, and how clients observe it.

POST /environments returns immediately with state="building" and an id. The platform provisions the task sandbox asynchronously; clients poll GET /environments/{id}/status until the state is terminal. The synchronous behavior — HTTP holding open for the full provision — was retired because it broke under fan-out (the CapabilityEnvAdapter pattern) and tripped client-side timeouts on cold image pulls.

Terminal window
dn env create security-mutillidae-sqli-login-bypass --wait
# state=building # fast initial response
# state=provisioning
# state=ready # service_urls + execute_token populated
StateMeaningservice_urlsexecute_tokenerror
buildingTask image isn’t cached; SandboxBuildsWorker is compiling it.nullnullnull
provisioningBuild is ready; the provider is bringing the sandbox up.nullnullnull
readySandbox is reachable. Run execute, read instructions, drive the agent.populatedpopulated (first poll after ready; one-shot)null
pausedSandbox is suspended (cost-saving, user action).populatednullnull
torn_downSandbox is terminated. Final state after DELETE.nullnullnull
failedBuild or provision failed. Inspect error and retry.nullnullpopulated

Transitions are monotonic with one exception: paused → ready when a paused sandbox resumes. Everything else flows forward.

GET /environments/{id}/status is the cheap polling endpoint — returns just the state snapshot. GET /environments/{id} returns the full resource with the same state-aware fields.

Terminal window
dn env status <env-id> --json
# {"id": "...", "state": "provisioning", "expires_at": null, "service_urls": null}

The SDK (dn.task_env(...) / TaskEnvironment.setup()) and the CLI (dn env create --wait) both poll transparently with exponential backoff (1s → 5s cap). Client-side deadline is the caller’s timeout_sec when set, else 15 minutes. A failed state raises RuntimeError with the server-provided error.

Peak concurrent task sandboxes for a CapabilityEnvAdapter run is concurrency × parallel_rows (candidates in parallel × dataset rows scored concurrently per candidate). The async POST /environments is what makes this composable — each provision returns quickly and the SDK handles the polling in the background, so a fan-out of 10 concurrent provisions doesn’t saturate the HTTP connection pool.

SymptomWhere to look
state="failed" with error: "task build failed: ..."Task image didn’t compile. Inspect dn task info <ref> or the task’s build logs.
state="failed" with error: "BadGatewayError: ..."Provider rejected the sandbox (resource limits, image missing architecture). Check the host Docker daemon or E2B provider.
state stuck in building past deadlineThe API restarted mid-provision. The in-process tracker is lost; poll returns 404 or stale state. Reprovision.
execute_token missing on readyYou polled /status after the first read consumed it. Stash the token the first time.