Skip to main content
A sandbox moves through a series of states during its lifetime. These states determine which operations are available and what actions the sandbox can make. In most cases, a sandbox starts in PENDING, moves to CREATING while the container is provisioned, and then enters RUNNING when the container is up. The RUNNING state is when you can perform most operations, such as running commands with Sandbox.exec(). When the main process of the sandbox exits, the sandbox enters a terminal state such as COMPLETED (if the exit code is 0) or FAILED (if there was an error). A sandbox can also be TERMINATED if it is externally killed or if it exceeds its maximum lifetime.
PENDING -> CREATING -> RUNNING -> COMPLETED
                               -> FAILED
                               -> TERMINATED
Use this page to understand when a sandbox is ready, how to wait for state changes, and how to stop a sandbox. The next sections provide details on sandbox states, waiting for a sandbox to start or complete, and stopping a sandbox. For more information on creating sandboxes and running commands, see Create sandboxes and Run commands.

Sandbox states

The following table summarizes the states of a sandbox:
StateDescription
PENDINGStart accepted, waiting for scheduling
CREATINGContainer is being provisioned
RUNNINGContainer is up, ready for operations
COMPLETEDMain process exited with code 0
FAILEDStartup or runtime error
TERMINATEDExternally killed or lifetime exceeded
A sandbox can accept most operations only after it reaches RUNNING. After it enters a terminal state, it is no longer available for additional work.

Wait for a sandbox to start

Use Sandbox.wait() when you want to confirm that the sandbox starts (sandbox reached RUNNING state) successfully before performing other operations, or when you want to separate startup errors from later command errors. For example, you might want to wait for the sandbox to fail early if there is a problem with the container image, network configuration, or other startup parameters before you upload files, install dependencies, or run a training script. The following code snippet shows how to wait for a sandbox to start:
import wandb
from wandb.sandbox import Sandbox, NetworkOptions

with Sandbox.run() as sandbox:
    sandbox.wait()  # block until the sandbox is running
    result = sandbox.exec(["python", "-c", "print('hello from sandbox')"]).result()
    print(result.stdout)

Wait for a sandbox to complete

Use Sandbox.wait_until_complete() when the sandbox’s main process represents the full workload and you want to wait for that job to finish.
from wandb.sandbox import Sandbox

with Sandbox.run("python", "train.py") as sandbox:
    sandbox.wait_until_complete(timeout=3600.0)  # block until the main process exits or timeout is reached
    print(f"Exit code: {sandbox.returncode}")
This pattern is useful when you start a sandbox with a main command such as Sandbox.run("python", "train.py") and want the sandbox lifecycle to match that command’s execution. When the main process exits, the sandbox enters a terminal state. A successful run typically ends in COMPLETED. If the process fails, the sandbox may enter FAILED.

Stop a sandbox

Use Sandbox.stop() when you no longer need the sandbox, when you want to end a long-running process, or when you need to clean up resources before the sandbox reaches its maximum lifetime.
from wandb.sandbox import Sandbox

with Sandbox.run("sleep", "infinity") as sandbox:
    sandbox.stop().result()
You can also control shutdown behavior with additional options:
from wandb.sandbox import Sandbox

with Sandbox.run("sleep", "infinity") as sandbox:
    sandbox.stop(
        graceful_shutdown_seconds=30.0,  # Wait before force-killing the sandbox.
        missing_ok=True,                 # Do not raise an error if it is already stopped.
    ).result()