# Cron Mode: execute_code Blocked ## Why It's Blocked `execute_code` runs arbitrary local Python, including `subprocess` calls that can bypass shell-string approval checks. In cron jobs, no user is present to approve these calls, so the tool is denied for safety. ## Error Signature When blocked, you see: ``` BLOCKED: execute_code runs arbitrary local Python (including subprocess calls that bypass shell-string approval checks). Cron jobs run without a user present to approve it. Use normal tools instead, or set approvals.cron_mode: approve only if this cron profile is intentionally trusted. ``` **Note on `approvals.cron_mode`:** The error message mentions this as a configuration option that could potentially enable `execute_code` in cron mode. However, this requires explicit user configuration of the cron profile as "intentionally trusted." Do NOT attempt to work around the block by trying different Python code — the restriction is at the tool-policy level, not the code level. If the user wants `execute_code` enabled in cron, they must configure it explicitly; the agent cannot and should not bypass this. ## Workaround Patterns ### Common Trigger: Batching `su` Commands via `subprocess` A frequent anti-pattern that triggers this block is attempting to use `execute_code` to run multiple `su -c` shell commands through Python's `subprocess` module: ```python # This WILL be blocked in cron mode: def su_run(cmd): full_cmd = f"su -c '{cmd}'" subprocess.run(full_cmd, shell=True, capture_output=True, text=True) # Then calling it repeatedly in a Python script: su_run("ls /sdcard/VisualAgent/commands/") su_run("cat /sdcard/VisualAgent/commands/cmd.json") su_run("screencap -p /sdcard/result.png") ``` **Why this is blocked**: The `subprocess` call with `shell=True` bypasses the shell-string approval mechanism. Even though each individual command is benign, the `execute_code` tool cannot verify this without running the code, which is exactly what the cron safety guard prevents. **The fix**: Replace the Python `subprocess` wrapper with direct `terminal` tool calls, one per operation. The `terminal` tool's shell-string approval mechanism can inspect each command individually and approve safe ones. ## Workaround Patterns ### Pattern 1: Terminal + Shell Commands (Recommended for Simple Tasks) Use `terminal` with `su -c` for each operation: ```bash # Check for commands su -c 'ls -la /sdcard/VisualAgent/commands/' # Read a command file su -c 'cat /sdcard/VisualAgent/commands/cmd_001.json' # Execute screenshot su -c 'screencap -p /sdcard/VisualAgent/results/screenshot.png' # Execute tap su -c 'input tap 500 1000' # Write result su -c 'echo "{\"status\":\"success\"}" > /sdcard/VisualAgent/results/result.json' ``` ### Pattern 2: Direct MCP Tools (Recommended for UI Operations) Use Hermes Android phone tools directly instead of shell commands: - `mcp_android_phone_screenshot` — captures screen via MCP - `mcp_android_phone_tap` — taps coordinates - `mcp_android_phone_swipe` — swipes screen - `mcp_android_phone_input_text` — types text - `mcp_android_phone_open_app` — launches app These are safer and don't require `execute_code`. ### Pattern 3: Shell + Python One-Liners (For JSON Parsing) When you need JSON parsing in shell, use `python3 -c`: ```bash # Extract command type from JSON su -c 'python3 -c "import json; print(json.load(open(\"/sdcard/VisualAgent/commands/cmd.json\")).get(\"type\"))"' # Parse and execute based on type su -c 'python3 -c " import json, subprocess, sys cmd = json.load(open(\"/sdcard/VisualAgent/commands/cmd.json\")) t = cmd.get(\"type\", \"\") if t == \"screenshot\": subprocess.run([\"screencap\", \"-p\", \"/sdcard/VisualAgent/results/screenshot.png\"]) "' ``` Note: This is still a shell command, not `execute_code`. The Python runs in a single `-c` string. However, **even `python3 -c` via `terminal` may fail in cron** if the command string is complex (contains quotes, newlines, or multiple statements). The `terminal` tool may also be blocked for long or complex shell strings in cron mode. Test with a simple one-liner first; if it fails, fall back to Pattern 4. ### Pattern 4: Hybrid — MCP Tools for Execution, Terminal for File I/O (Most Reliable in Cron) For the VisualAgent pattern, use MCP tools for UI operations and terminal for file management: 1. `terminal` to list command files: `su -c 'ls /sdcard/VisualAgent/commands/'` 2. `terminal` to read command: `su -c 'cat /sdcard/VisualAgent/commands/cmd.json'` 3. MCP tool to execute (e.g., `mcp_android_phone_screenshot`) 4. `terminal` to write result: `su -c 'echo "..." > /sdcard/VisualAgent/results/result.json'` ## What NOT to Do - ❌ Don't try to use `execute_code` with `subprocess` in cron — it will be blocked - ❌ Don't write a Python script to a file and try to run it via `execute_code` - ❌ Don't attempt to bypass the block with creative workarounds — use the approved patterns above - ❌ Don't try to use `execute_code` for complex multi-step logic with loops/conditionals — break it into separate `terminal` calls instead ## When execute_code IS Available `execute_code` works normally in interactive sessions (when a user is present). The block only applies to cron jobs and other non-interactive contexts where no user can approve potentially dangerous operations. ## Real-World Recovery Example If you accidentally try `execute_code` and get blocked: 1. **Recognize the error** — "BLOCKED: execute_code runs arbitrary local Python..." 2. **Stop** — don't try again or look for workarounds 3. **Switch to Pattern 4 (Hybrid)** — use `terminal` for file I/O and MCP tools for UI execution 4. **For JSON parsing** — use `python3 -c` via `terminal` or `jq` if available Example recovery from a blocked VisualAgent service attempt: ``` # Was going to do this (BLOCKED): # execute_code with Python script that loops, parses JSON, calls subprocess # Instead do this: terminal: "su -c 'ls -la /sdcard/VisualAgent/commands/'" # → see files, identify commands terminal: "su -c 'cat /sdcard/VisualAgent/commands/cmd.json'" # → read command content mcp_android_phone_screenshot: {path: "/sdcard/VisualAgent/results/screenshot.png"} # → execute screenshot via MCP terminal: "su -c 'echo \"{\\"status\\":\\"success\\"}\" > /sdcard/VisualAgent/results/result.json'" # → write result ```