{"record":{"id":"aa683c55451bd1bc","repo":"huggingface/open-r1","slug":"no-piston-endpoints-provided-please-check-your-pi","errorCode":null,"errorMessage":"No Piston endpoints provided. Please check your PISTON_ENDPOINTS environment variable.","messagePattern":"No Piston endpoints provided\\. Please check your PISTON_ENDPOINTS environment variable\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/open_r1/utils/competitive_programming/piston_client.py","lineNumber":68,"sourceCode":"    sed -i '/app.use(body_parser.urlencoded/c\\    app.use(body_parser.urlencoded({ extended: true, limit: \\\"512mb\\\" }));' src/index.js\n    sed -i '/app.use(body_parser.json/c\\    app.use(body_parser.json({ limit: \\\"512mb\\\" }));' src/index.js\n\n    # Start server in background\n    node src```\n\n    Piston docs for API usage: https://piston.readthedocs.io/en/latest/api-v2/\n    \"\"\"\n\n    def __init__(\n        self,\n        base_endpoint: str | list[str] = \"http://ip-10-53-80-65:3223/api/v2\",\n        session=None,\n        max_requests_per_endpoint=1,\n    ):\n        self.max_requests_per_endpoint = max_requests_per_endpoint\n        self.base_endpoints = [base_endpoint] if isinstance(base_endpoint, str) else base_endpoint\n        if len(self.base_endpoints) == 0:\n            raise ValueError(\"No Piston endpoints provided. Please check your PISTON_ENDPOINTS environment variable.\")\n        self.endpoint_ids = {endpoint: i for i, endpoint in enumerate(self.base_endpoints)}\n\n        self._session = session\n        self.endpoint_tokens = asyncio.Queue(maxsize=max_requests_per_endpoint * len(self.base_endpoints))\n\n        for _ in range(max_requests_per_endpoint):\n            for base_endpoint in self.base_endpoints:\n                self.endpoint_tokens.put_nowait(base_endpoint)\n        self._endpoint_failures = Counter()\n        self._unhealthy_endpoints = set()\n        self._endpoint_failures_lock = asyncio.Lock()\n\n    @property\n    def session(self):\n        if self._session is None:\n            self._session = aiohttp.ClientSession(\n                timeout=aiohttp.ClientTimeout(sock_read=30),\n                connector=aiohttp.TCPConnector(","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/huggingface/open-r1/blob/1416fa0cf21595d2083b399a2a0bbddd7f6e9563/src/open_r1/utils/competitive_programming/piston_client.py#L50-L86","documentation":"The PistonClient constructor normalizes base_endpoint into a list; if the resulting list is empty, there is nothing to send requests to, so __init__ raises ValueError. This is a defensive check for an explicitly-provided-but-empty endpoint list.","triggerScenarios":"PistonClient(base_endpoint=[]) constructed directly, or PISTON_ENDPOINTS set to an empty string / a value that splits into zero entries (e.g. PISTON_ENDPOINTS=','), bypassing the earlier None-check in get_piston_client_from_env.","commonSituations":"PISTON_ENDPOINTS='' in .env; a filtering step that removed all endpoints before constructing the client; programmatic construction passing an empty list after unhealthy-endpoint pruning.","solutions":["Populate PISTON_ENDPOINTS with at least one reachable endpoint URL.","If constructing PistonClient directly, pass a non-empty list or string of endpoints.","Guard your config-loading code: strip whitespace and filter empty strings from the split list before instantiation.","Check code paths that prune unhealthy endpoints so they don't hand an empty list to a new client."],"exampleFix":"// before\nendpoints = [e for e in os.getenv('PISTON_ENDPOINTS','').split(',') if e] or []\nclient = PistonClient(endpoints)  # ValueError\n// after\nassert endpoints, 'PISTON_ENDPOINTS must contain at least one endpoint'\nclient = PistonClient(endpoints)","handlingStrategy":"validation","validationCode":"raw = os.getenv('PISTON_ENDPOINTS', '')\nendpoints = [e.strip() for e in raw.split(',') if e.strip()] if raw != 'slurm' else get_slurm_piston_endpoints()\nassert endpoints, 'PISTON_ENDPOINTS resolved to an empty endpoint list'","typeGuard":"def has_endpoints(x) -> bool:\n    eps = [x] if isinstance(x, str) else (x or [])\n    return len(eps) > 0 and all(isinstance(e, str) and e.strip() for e in eps)","tryCatchPattern":"try:\n    client = PistonClient(base_endpoint=endpoints)\nexcept ValueError as e:\n    if 'No Piston endpoints' in str(e):\n        raise SystemExit('Provide at least one Piston endpoint') from e\n    raise","preventionTips":["Never set PISTON_ENDPOINTS to an empty string; comment it out instead","Filter empty entries after splitting the comma-separated list","Guard code that prunes unhealthy endpoints from producing empty lists"],"tags":["piston","configuration","empty-list"],"backgroundTag":"missing-env-var","analyzedSha":"1416fa0cf21595d2083b399a2a0bbddd7f6e9563","analyzedAt":"2026-08-30T08:56:53.400Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}