After updating to 2026.3.8, my bot executes simple commands (date, hostname, ls) correctly via exec but will not execute Python scripts — it generates fake JSON output instead. tools.profile=coding is set, sandbox=off, fs.workspaceOnly=false. Primary model is openai-codex/gpt-5.4-codex. Has anyone solved Python script exec being silently blocked post-3.8
#3.8 Exec Bug?
1 messages · Page 1 of 1 (latest)
This usually isn’t “Python blocked”, it’s exec allowlist/approval kicking in harder in newer builds.
In 2026.3.x, exec on a real host (host=gateway / host=node, and also when sandboxing is off) defaults to security=allowlist + ask=on-miss unless you’ve explicitly changed it. That means basic safe stuff like date/ls/hostname often works, but interpreters (python3, node, etc.) get denied unless they’re explicitly allowlisted (and you’ll see it in logs as SYSTEM_RUN_DENIED: allowlist miss or ... approval required). Docs: https://docs.openclaw.ai/tools/exec and https://docs.openclaw.ai/tools/exec-approvals
What I’d do to confirm quickly:
- Check what exec is doing in this session
- Send
/exec(with no args) and paste what it reports forhost/security/ask.
- Try the minimal probes
which python3python3 --version
- Tail logs while you try it
openclaw logs --follow
You’re looking for:SYSTEM_RUN_DENIED: allowlist miss
SYSTEM_RUN_DENIED: approval required
If that’s the case, fix is to allowlist the python binary (gateway or node, depending where you run exec):
- Via CLI:
openclaw approvals allowlist add --agent main --gateway "/usr/bin/python3"
# or on mac/homebrew commonly:
openclaw approvals allowlist add --agent main --gateway "/opt/homebrew/bin/python3"
- Or via UI: Control UI → Nodes → Exec approvals (target “Gateway” vs the node), then add the python3 path and save.
One extra gotcha: in allowlist mode it matches resolved binary paths, not just python3 by name.
If you paste:
openclaw --version
/execoutput- the relevant
SYSTEM_RUN_DENIED...log line (if any)
…I can tell you exactly whether it’s allowlist, approval prompts not reaching you, or something else.
-
Current exec defaults: host=sandbox, security=deny, ask=on-miss, node=(unset).
Options: host=sandbox|gateway|node, security=deny|allowlist|full, ask=off|on-miss|always, node=<id>. -
/usr/bin/python3
Python 3.12.3
- did not find those
That /exec output is the key: you’re currently running exec in host=sandbox.
So which python3 / python3 --version succeeding just proves Python exists inside the Docker sandbox. But if the .py you’re trying to run lives on the gateway host filesystem (or anywhere not inside the sandbox workspace), the sandbox simply can’t see it unless you bind-mount it — and a lot of models will “helpfully” hallucinate output instead of surfacing the real No such file / denial.
Two quick ways to make this concrete:
A) Confirm whether the script is visible from exec’s POV
Run via exec:
pwdls -lals -la /path/to/your_script.py(the exact path you use)
If that ls can’t see it, Python can’t run it either.
B) Fix paths depending on what you want
Option 1 — Keep host=sandbox (recommended for safety):
Bind-mount the host folder that contains your scripts into the sandbox. FAQ section: https://docs.openclaw.ai/help/faq#how-do-i-bind-a-host-folder-into-the-sandbox
(agents.defaults.sandbox.docker.binds: ["host:path:mode"])
Option 2 — Actually run on the host (host=gateway):
Set per-session:
/exec host=gateway security=allowlist ask=on-miss
Then, if Python gets denied, you’ll need to allowlist the interpreter path (because host exec defaults to allowlist/approvals):
- https://docs.openclaw.ai/tools/exec-approvals
- CLI helper: https://docs.openclaw.ai/cli/approvals
Example:
openclaw approvals allowlist add --agent main --gateway "/usr/bin/python3"
If you paste the exact command you’re running for the script (including the script path), I can tell you immediately which of the two cases you’re in (sandbox-can’t-see-file vs host allowlist denial).
Nice — if pwd/ls can see the .py, then it’s not a sandbox visibility/bind-mount issue.
Next thing to pin down is: is the exec tool actually running the script and returning stderr/exit code, or is the model just “simulating” the run in chat.
Can you paste the exact failing command you’re running (e.g. python3 ./foo.py --args ...) and what you get back?
Two quick probes that make this unambiguous:
- Minimal inline Python (should always work if exec is real):
python3 -c 'import json; print(json.dumps({"ok": True}))'
- Run your script with unbuffered output and capture real errors:
python3 -u ./your_script.py
echo "exit=$?"
While doing (2), also run:
openclaw logs --follow
and look for any SYSTEM_RUN_DENIED... (policy/allowlist) vs a normal “exec started/finished” with a nonzero exit (script crash / missing deps).
If the logs show no exec invocation at all when you ask it to run the script, that’s a model/tool-use behavior issue (it’s choosing to answer instead of calling exec). If the logs show the exec ran and exited nonzero, paste the stderr and we can fix the actual Python/runtime problem.
python3 ./foo.py --args
python3: can't open file '/home/affinitas/./foo.py': [Errno 2] No such file or directory
python3 -c 'import json; print(json.dumps({"ok": True}))'
{"ok": true}
That output means exec is working and Python isn’t being blocked — it’s just running in a directory where foo.py doesn’t exist:
python3: can't open file '/home/affinitas/./foo.py': [Errno 2] No such file or directory
So the fix is simply to run it from the right place (or use an absolute path):
-
Absolute path:
python3 /full/path/to/foo.py --args -
Or set the exec working directory (best practice with OpenClaw’s exec tool — it supports
workdir):- Ask the bot explicitly: “Use the exec tool with
workdirset to the folder that containsfoo.py, then runpython3 foo.py …” - Docs: https://docs.openclaw.ai/tools/exec (see
workdir)
- Ask the bot explicitly: “Use the exec tool with