Fixes a regression where 'openclaw-sandbox:bookworm-slim' was created by
pulling debian:bookworm-slim (which has no python3), causing file write/edit
tools to fail with 'python3: not found' inside the sandbox container.
Before: always pulled debian:bookworm-slim (no python3)
After: tries ghcr.io/openclaw/openclaw:main-slim-amd64 first (has python3),
falls back to building locally from Dockerfile.sandbox if needed.
Fixesopenclaw/openclaw#51099
This ensures that when workspaceAccess is set to 'ro' or 'none', the
sandbox workspace (/workspace inside the container) is mounted as
read-only, matching the documented behavior.
Previously, the condition was:
workspaceAccess === 'ro' && workspaceDir === agentWorkspaceDir
This was always false in 'ro' mode because workspaceDir equals
sandboxWorkspaceDir, not agentWorkspaceDir.
Now the logic is simplified:
- 'rw': /workspace is writable
- 'ro': /workspace is read-only
- 'none': /workspace is read-only
* fix(sandbox): prevent Windows PATH from poisoning docker exec shell lookup
On Windows hosts, `buildDockerExecArgs` passes the host PATH env var
(containing Windows paths like `C:\Windows\System32`) to `docker exec -e
PATH=...`. Docker uses this PATH to resolve the executable argument
(`sh`), which fails because Windows paths don't exist in the Linux
container — producing `exec: "sh": executable file not found in $PATH`.
Two changes:
- Skip PATH in the `-e` env loop (it's already handled separately via
OPENCLAW_PREPEND_PATH + shell export)
- Use absolute `/bin/sh` instead of bare `sh` to eliminate PATH
dependency entirely
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* style: add braces around continue to satisfy linter
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(test): update assertion to match /bin/sh in buildDockerExecArgs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Previously, `dockerImageExists` assumed any error from `docker image inspect` meant the image did not exist. This masked other errors like socket permission issues.
This change:
- Modifies `dockerImageExists` to inspect stderr when the exit code is non-zero.
- Returns `false` only if the error explicitly indicates "No such image" or "No such object".
- Throws an error with the stderr content for all other failures.
- Adds a reproduction test in `src/agents/sandbox/docker.test.ts`.