Skip to content

[Bug]: Sandbox exec: workdir path not mapped + stdout lost on background transition #30711

@aaajiao

Description

@aaajiao

Summary

Sandbox exec has two reliability issues that cause bun (and likely other runtimes) to produce no captured output:

  1. workdir parameter doesn't map host↔container paths — passing workdir: "/workspace" fails because the Gateway validates the path on the host side, where /workspace doesn't exist.
  2. stdout lost during yieldMs background transition — when a bun process runs longer than yieldMs (default 10s), stdout output is silently dropped. The process exits code 0 but process log shows "(no output recorded)".

Steps to reproduce

Issue 1: workdir path mapping

{ "tool": "exec", "command": "bun scripts/xsearch.js 'test'", "workdir": "/workspace" }

Result:

Warning: workdir "/workspace" is unavailable; using "/home/<user>/.openclaw/workspace".
sh: 1: cd: can't cd to /home/<user>/.openclaw/workspace

The Gateway resolves workdir against the host filesystem. /workspace doesn't exist on the host, so it falls back to the host workspace path — which doesn't exist inside the container.

Issue 2: stdout dropped on background transition

{ "tool": "exec", "command": "bun scripts/xsearch.js 'query' --x", "timeout": 30 }

The xAI API call takes >10s. The exec tool backgrounds the process at yieldMs=10000. After the process completes (code 0), process log returns empty.

Workaround that fixes it:

{ "tool": "exec", "command": "bun scripts/xsearch.js 'query' --x 2>&1", "timeout": 30 }

Adding 2>&1 reliably captures all output.

Expected behavior

  1. workdir: "/workspace" should resolve correctly inside sandbox containers (the mount target is /workspace).
  2. All stdout should be captured regardless of whether the process exceeds yieldMs and gets backgrounded.

Analysis

Issue 1

The workdir parameter is validated on the Gateway/host side before being passed to the container. In sandbox mode with workspaceAccess: "rw", the host workspace (e.g. /home/user/.openclaw/workspace) is mounted at /workspace inside the container. The Gateway should either:

  • Map known mount points (host workspace path ↔ /workspace)
  • Or validate workdir inside the container, not on the host

Issue 2

Sandbox exec runs sh -lc with stdout connected via pipe. Bun uses block-buffered stdout when connected to a pipe (standard libc behavior — not a TTY, so no line buffering). When the exec tool transitions to background mode at yieldMs, the pipe read-end appears to not fully drain the buffer. The 2>&1 workaround changes the fd topology and likely hits a different capture code path that handles the drain correctly.

This likely affects any runtime with block-buffered stdout (not just bun) when commands exceed yieldMs.

Current workaround

A shell wrapper that handles both issues:

#!/bin/bash
cd /workspace 2>/dev/null || exit 1
exec bun "$@" 2>&1

Environment

  • OpenClaw v2026.2.26
  • Sandbox mode: all, scope: shared, workspaceAccess: rw
  • Container: openclaw-sandbox:bookworm-slim
  • Runtime: bun 1.3.10 (also likely affects node/python with long-running commands)
  • Host: Linux arm64 (OrbStack VM)

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions