Skip to main content
When you run a command in a sandbox, its stdout and stderr output can be consumed in two ways: streamed in real time through callbacks, or retrieved in full after the command finishes. Real-time streaming suits long-running or background commands you want to monitor as they run; retrieving the full output suits commands with a predictable, short duration.

Stream logs with callbacks

Pass onStdout / onStderr (JavaScript) or on_stdout / on_stderr (Python) to commands.run(...). Each callback receives output as soon as it is produced, with stdout and stderr delivered separately.
Keep callbacks lightweight. Avoid long blocking work inside a callback — it holds up event processing and can cause the underlying connection to disconnect. Buffer or hand off to another task/thread if you need to do heavy processing.

Stream a background command

To keep your program running while a command streams, start it with background: true (JS) or background=True (Python). This returns a CommandHandle instead of waiting for the result. You can attach the same onStdout / onStderr callbacks, continue with other work, then call wait() to block until the command finishes and get its CommandResult.

Retrieve all logs after completion

If you do not need real-time output, run the command in the foreground and read the full stdout and stderr from the returned CommandResult. This is the simplest approach for commands with a predictable, short duration.
For a command started in the background, the accumulated output is also available on the handle after it completes.

CommandResult fields

A command that exits with a non-zero exit code raises CommandExitError (JS) / CommandExitException (Python). The exception carries the same stdout, stderr, exitCode, and error fields, so you can still inspect the output on failure.
Last modified on August 5, 2026