agentscope-ai/agentscope · critical · RuntimeError
gateway shim produced non-JSON stdout: {result.stdout[:200]!
Error message
gateway shim produced non-JSON stdout: {result.stdout[:200]!r} What it means
Raised by GatewayClient.exec_request() when the in-sandbox shim exits 0 but its stdout is not parseable JSON. The shim is expected to print exactly one JSON envelope ({status, body/body_file, ...}); anything else (empty stdout, warnings printed to stdout, partial output) triggers this. The first 200 bytes of stdout are shown repr-escaped for diagnosis.
Source
Thrown at src/agentscope/workspace/_gateway_client.py:678
timeout=self.timeout,
)
finally:
if wrote_body_file is not None:
try:
await self.backend.delete_path(wrote_body_file)
except Exception:
pass
if result.exit_code != 0:
raise RuntimeError(
f"gateway shim exited with {result.exit_code}: "
f"{result.stderr.decode(errors='replace')[:500]}",
)
try:
env = json.loads(result.stdout)
except Exception as e:
raise RuntimeError(
"gateway shim produced non-JSON stdout: "
f"{result.stdout[:200]!r}",
) from e
status = int(env["status"])
if status == -1:
raise RuntimeError(
"gateway request failed: "
f"{env.get('error', 'unknown error')}",
)
if "body_file" in env:
spilled = env["body_file"]
body_bytes = await self.backend.read_file(spilled)
try:
await self.backend.delete_path(spilled)
except Exception:
passView on GitHub (pinned to e90f1c7592)
Solutions
- Inspect the repr'd stdout prefix in the message — warnings or partial JSON reveal the cause
- Ensure the backend's exec captures stdout/stderr as separate streams (no TTY merging)
- Set PYTHONWARNINGS=ignore / -W ignore for the sandbox python if warnings leak to stdout
- Redeploy so SHIM_SCRIPT and sandbox python3 versions match
Defensive patterns
Strategy: fallback
Validate before calling
res = await backend.exec_shell(["python3", "-c", "import json;print(json.dumps({'ok':1}))"])
if not res.ok() or not res.stdout.strip().startswith(b"{"):
raise RuntimeError("sandbox python stdout is polluted") Try / catch
try:
status, body = await gateway.exec_request(...)
except RuntimeError as e:
if "non-JSON stdout" in str(e):
logger.error("shim stdout polluted; inspect backend exec stream config")
raise Prevention
- Keep exec stdout/stderr as separate streams (no TTY)
- Set PYTHONWARNINGS=ignore in the sandbox environment
- Version-lock the client library and sandbox image
When it happens
Trigger: Any gateway call where the shim's stdout is empty (killed mid-print), where the sandbox merges stderr into stdout (site warnings, deprecation notices), or where a different process/echo interferes with the exec stream.
Common situations: Sandbox TTY/exec config merging stderr into stdout; PYTHONWARNINGS or import-time warnings printed to stdout; shim killed by signal producing truncated stdout; version skew between SHIM_SCRIPT and what the sandbox's python3 supports.
Related errors
- gateway shim exited with {result.exit_code}: {result.stderr.
- gateway request failed: {env.get('error', 'unknown error')}
- <system-reminder>{error_message} Your argument string is de
- {left_name} must not overlap {right_name}.
- not found in Bubblewrap sandbox: {path}
AI-assisted analysis of agentscope-ai/agentscope@e90f1c7592 (2026-08-28).
Data as JSON: /api/errors/29b349ec53ced8db.
Report an issue: GitHub.