From 8f91c1d38f32a83de9ff3b4d2a8066e7c356bc45 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sun, 3 May 2026 12:33:46 +0800 Subject: [PATCH] Reject string-like shell commands --- src/agents/run_internal/tool_execution.py | 4 ++++ tests/test_shell_call_serialization.py | 7 +++++++ 2 files changed, 11 insertions(+) diff --git a/src/agents/run_internal/tool_execution.py b/src/agents/run_internal/tool_execution.py index 421ee05a54..b48adbf2b0 100644 --- a/src/agents/run_internal/tool_execution.py +++ b/src/agents/run_internal/tool_execution.py @@ -619,6 +619,10 @@ def coerce_shell_call(tool_call: Any) -> ShellCallData: raise ModelBehaviorError("Shell call is missing an action payload.") commands_value = get_mapping_or_attr(action_payload, "commands") + if isinstance(commands_value, (str, bytes, bytearray)): + raise ModelBehaviorError( + "Shell call action commands must be a list of strings, not a single string-like value." + ) if not isinstance(commands_value, Sequence): raise ModelBehaviorError("Shell call action is missing commands.") commands: list[str] = [] diff --git a/tests/test_shell_call_serialization.py b/tests/test_shell_call_serialization.py index f21f028a72..8c1d5e20eb 100644 --- a/tests/test_shell_call_serialization.py +++ b/tests/test_shell_call_serialization.py @@ -29,6 +29,13 @@ def test_coerce_shell_call_requires_commands() -> None: run_loop.coerce_shell_call(tool_call) +def test_coerce_shell_call_rejects_string_like_commands() -> None: + for commands in ("echo hi", b"echo hi", bytearray(b"echo hi")): + tool_call = {"call_id": "shell-3", "action": {"commands": commands}} + with pytest.raises(ModelBehaviorError, match="list of strings"): + run_loop.coerce_shell_call(tool_call) + + def test_normalize_shell_output_handles_timeout() -> None: entry = { "stdout": "",