diff --git a/gateway/run.py b/gateway/run.py index 5027c800ea0c..e1a58af13400 100644 --- a/gateway/run.py +++ b/gateway/run.py @@ -12583,7 +12583,11 @@ async def _handle_update_command(self, event: MessageEvent) -> str: update_cmd = ( f"PYTHONUNBUFFERED=1 {hermes_cmd_str} update --gateway" f" > {shlex.quote(str(output_path))} 2>&1; " - f"status=$?; printf '%s' \"$status\" > {shlex.quote(str(exit_code_path))}" + # Avoid `status=$?`: `status` is a read-only special parameter + # in zsh, and this command string is copied/reused in macOS/zsh + # operator wrappers. Keep the template zsh-safe even though this + # specific subprocess currently runs under bash. + f"rc=$?; printf '%s' \"$rc\" > {shlex.quote(str(exit_code_path))}" ) setsid_bin = shutil.which("setsid") if setsid_bin: diff --git a/tests/gateway/test_update_streaming.py b/tests/gateway/test_update_streaming.py index 932bd1b05790..eb0f0cfa8905 100644 --- a/tests/gateway/test_update_streaming.py +++ b/tests/gateway/test_update_streaming.py @@ -237,6 +237,8 @@ async def test_spawns_with_gateway_flag(self, tmp_path): cmd_string = call_args[-1] if isinstance(call_args, list) else str(call_args) assert "--gateway" in cmd_string assert "PYTHONUNBUFFERED" in cmd_string + assert "rc=$?" in cmd_string + assert "status=$?" not in cmd_string assert "stream progress" in result