huggingface/open-r1 · error · PistonError
{response}
Error message
{response} What it means
After handling compilation, execute_ioi requires a 'run' key in the Piston response. If the response has no 'run' entry, the whole response object is raised as PistonError, because Piston only omits 'run' when the submission never actually executed (API-level failure, malformed response, or language/version not resolved).
Source
Thrown at src/open_r1/utils/competitive_programming/ioi_scoring.py:318
async def execute_ioi(client, data) -> tuple[str, str]:
"""
Requests to the IOI package return the score as a float in the stdout, as well as optional feedback/errors in stderr.
Returns a tuple of (score, feedback).
"""
response = await client.send_execute(data)
if "message" in response:
raise PistonError(response["message"])
if "compile" in response and response["compile"]["code"] != 0:
return "0", "Compilation error exit code " + str(response["compile"]["code"]) + "\n" + response["compile"][
"stderr"
]
if "run" not in response:
raise PistonError(response)
if response["run"]["code"] == 1 and "MemoryError" in response["run"]["stderr"]:
return "0", "Memory limit exceeded"
# successful result
if response["run"]["stdout"]:
return response["run"]["stdout"], response["run"]["stderr"]
if response["run"]["signal"] == "SIGKILL":
return "0", "Time limit exceeded"
# other issues
if response["run"]["code"] != 0:
raise PistonError(
f"language={response['language']}, version={response['version']}, exit code={response['run']['code']}, stderr={response['run']['stderr']}, signal={response['run']['signal']}"
)
return "0", "Unknown error"
View on GitHub (pinned to 1416fa0cf2)
Solutions
- Inspect the full response printed in the error — it shows exactly what the endpoint returned and usually reveals the real cause (e.g. 'language cms_ioi not found').
- Confirm the endpoint exposes the cms_ioi runtime via GET /api/v2/runtimes; reinstall the IOI package if missing.
- Check for proxies/CDNs between client and worker that may strip or reshape the JSON response.
- Update the piston client/IOI package if the endpoint's response schema changed.
Example fix
// before: raw response dict in error
raise PistonError(response)
// after: log with context
raise PistonError(f"No 'run' in Piston response: {json.dumps(response)[:2000]}") Defensive patterns
Strategy: validation
Validate before calling
required = {'compile', 'run'}
missing = required - set(response.keys())
if missing and 'message' not in response:
raise RuntimeError(f'Unexpected Piston response shape, missing {missing}: {response}') Type guard
def has_run_result(resp: dict) -> bool:
run = resp.get('run') if isinstance(resp, dict) else None
return isinstance(run, dict) and 'code' in run Try / catch
try:
result = await execute_ioi(client, data)
except PistonError as e:
if 'cms_ioi not found' in str(e) or "'run'" in str(e):
await mark_endpoint_unhealthy(endpoint)
raise Prevention
- Pin the same IOI package/schema version on client and workers
- Avoid proxies that rewrite Piston JSON bodies
- Assert response schema in an integration test against your real workers
When it happens
Trigger: send_execute returns a dict lacking 'run' — typically a Piston error body that happened to carry no top-level 'message' key (e.g. partial/odd response shape from a proxy, or a runtime that failed to install), so the guard on 'message' at line ~310 didn't fire.
Common situations: Reverse proxy or load balancer in front of Piston rewriting error bodies; a custom IOI package whose language runtime failed to install on the worker; endpoint version mismatch returning an unexpected schema.
Related errors
- {response['message']}
- language={response['language']}, version={response['version'
- Compilation error exit code {compile_result.exit_code} {comp
- For IOI/CF problems Piston endpoints running our IOI package
- No Piston endpoints provided. Please check your PISTON_ENDPO
AI-assisted analysis of huggingface/open-r1@1416fa0cf2 (2026-08-30).
Data as JSON: /api/errors/394a7afa1e1d20a4.
Report an issue: GitHub.