Skip to content

Commit 6c908be

Browse files
fix: use shell wrapper with stdin redirect for Claude CLI
Modal sandbox sb.exec() doesn't properly close stdin, causing Claude to hang. Using sh -c with < /dev/null fixes this.
1 parent b500446 commit 6c908be

1 file changed

Lines changed: 10 additions & 11 deletions

File tree

src/policyengine_api/agent_sandbox.py

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -99,21 +99,20 @@ def run_claude_code_in_sandbox(
9999

100100
# Run Claude Code with the question
101101
# Note: Can't use --dangerously-skip-permissions as root (Modal runs as root)
102+
# Use shell wrapper with </dev/null to properly close stdin (prevents hanging)
102103
# --max-turns: limit execution to prevent runaway
103104
print("[SANDBOX] Starting claude CLI with question", flush=True)
104105
logfire.info("run_claude_code_in_sandbox: starting claude CLI")
105-
process = sb.exec(
106-
"claude",
107-
"-p",
108-
question,
109-
"--output-format",
110-
"stream-json",
111-
"--verbose",
112-
"--max-turns",
113-
"10",
114-
"--allowedTools",
115-
"mcp__policyengine__*,Bash,Read,Grep,Glob,Write,Edit",
106+
107+
# Escape the question for shell
108+
escaped_question = question.replace("'", "'\"'\"'")
109+
cmd = (
110+
f"claude -p '{escaped_question}' "
111+
"--output-format stream-json --verbose --max-turns 10 "
112+
"--allowedTools 'mcp__policyengine__*,Bash,Read,Grep,Glob,Write,Edit' "
113+
"< /dev/null 2>&1"
116114
)
115+
process = sb.exec("sh", "-c", cmd)
117116
print("[SANDBOX] claude CLI process started", flush=True)
118117
logfire.info("run_claude_code_in_sandbox: claude CLI process started, returning")
119118

0 commit comments

Comments
 (0)