huggingface/open-r1 · error · PistonError

{response['message']}

Error message

{response['message']}

What it means

execute_ioi raises PistonError when the Piston IOI package response contains a top-level 'message' key. Piston uses 'message' to report API-level failures (bad request, unsupported language/version, internal worker error) instead of a compile/run result. The library surfaces that message verbatim so the caller sees the remote engine's reason for refusing the submission.

Source

Thrown at src/open_r1/utils/competitive_programming/ioi_scoring.py:310

            *({"name": name, "content": content} for name, content in problem["grader_files"] if content),
        ],
        "run_timeout": round(
            (problem["time_limit"] + 3) * 1000
        ),  # +3 seconds hard limit. time limits are handled by the ioi script
        "run_memory_limit": problem["memory_limit"],
    }
    return await execute_ioi(client, data)


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"

View on GitHub (pinned to 1416fa0cf2)

Solutions

  1. Verify the endpoint serves the custom cms_ioi language: curl <endpoint>/api/v2/runtimes and confirm cms_ioi is listed; if not, deploy the IOI package or point PISTON_ENDPOINTS at a valid endpoint.
  2. Read the raised message text — it contains Piston's own reason (unknown language/version etc.) and fix the request accordingly.
  3. Check that the Piston worker is healthy and reachable; replace unhealthy endpoints in PISTON_ENDPOINTS.
  4. Retry with a different endpoint if the error is transient (the client round-robins endpoints).

Example fix

// before: any Piston endpoint
PISTON_ENDPOINTS=https://emkc.org/api/v2/piston
// after: endpoint running the IOI package
PISTON_ENDPOINTS=http://my-piston-host:2000
Defensive patterns

Strategy: try-catch

Validate before calling

import httpx
runtimes = httpx.get(f'{endpoint}/api/v2/runtimes').json()
assert any(rt['language'] == 'cms_ioi' for rt in runtimes), 'endpoint lacks cms_ioi runtime'

Type guard

def has_message(resp: dict) -> bool:
    return isinstance(resp, dict) and isinstance(resp.get('message'), str)

Try / catch

try:
    score, feedback = await run_submission(...)
except PistonError as e:
    logger.error('Piston rejected execution: %s', e)
    score, feedback = '0', f'Execution infrastructure error: {e}'

Prevention

When it happens

Trigger: A call to run_submission -> execute_ioi where client.send_execute(data) returns a dict containing key 'message' — e.g. the endpoint doesn't have the cms_ioi language installed, the request payload is malformed, or the Piston worker returns an HTTP-level error body.

Common situations: Pointing PISTON_ENDPOINTS at a vanilla Piston instance without the custom IOI package; submitting a language version string Piston can't resolve; Piston worker returning 4xx/5xx JSON with a message field; rate-limited or overloaded worker.

Related errors


AI-assisted analysis of huggingface/open-r1@1416fa0cf2 (2026-08-30). Data as JSON: /api/errors/ce21c3ef56e187a7. Report an issue: GitHub.