{"record":{"id":"f52872f3ddb12fc7","repo":"huggingface/open-r1","slug":"could-not-determine-problem-id-from-files","errorCode":null,"errorMessage":"Could not determine problem ID from files","messagePattern":"Could not determine problem ID from files","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/open_r1/utils/competitive_programming/morph_client.py","lineNumber":109,"sourceCode":"            tuple: (problem_id, grader_config, local_files)\n\n        Raises:\n            ValueError: If problem ID cannot be determined\n        \"\"\"\n        # Extract problem ID\n        problem_id = None\n        graders_files = []\n        for file in data[\"files\"]:\n            if file[\"name\"].startswith(\"graders/\") and file[\"name\"].endswith(\".cpp\"):\n                potential_id = os.path.basename(file[\"name\"]).split(\".\")[0]\n                if potential_id not in [\"grader\", \"manager\", \"stub\"]:\n                    problem_id = potential_id\n\n            if file[\"name\"].startswith(\"graders/\"):\n                graders_files.append(file)\n\n        if not problem_id:\n            raise ValueError(\"Could not determine problem ID from files\")\n\n        grader_config = {\n            \"task_type\": \"Batch\",\n            \"code\": problem_id,\n            \"time_limit\": data[\"run_timeout\"] / 1000,\n            \"memory_limit\": data[\"run_memory_limit\"] * 1024 * 1024,\n        }\n\n        for file in graders_files:\n            if \"manager.cpp\" in file[\"name\"]:\n                grader_config[\"task_type\"] = \"Communication\"\n                grader_config[\"task_type_parameters_Communication_num_processes\"] = 1\n                grader_config[\"task_type_parameters_Communication_user_io\"] = \"std_io\"\n                break\n\n        config_path = os.path.join(temp_dir, \"grader_config.json\")\n        with open(config_path, \"w\") as f:\n            json.dump(grader_config, f)","sourceCodeStart":91,"sourceCodeEnd":127,"githubUrl":"https://github.com/huggingface/open-r1/blob/1416fa0cf21595d2083b399a2a0bbddd7f6e9563/src/open_r1/utils/competitive_programming/morph_client.py#L91-L127","documentation":"The MorphCloud morph_client derives the IOI problem ID by scanning the uploaded files (looking for filenames that identify the problem, e.g. a task folder or graders layout). If no file name yields a recognizable problem ID, _prepare_files raises ValueError before building the grader config.","triggerScenarios":"Calling _execute_with_instance with a data['files'] list whose 'name' fields don't match the patterns _prepare_files checks (no problem-id-like name, no 'graders/' prefix structure) — e.g. files uploaded as 'sol.cpp' / 'main.cpp' without any problem-identifying path component.","commonSituations":"Adapting the client to a new problem package whose directory layout differs; flat uploads that stripped directory prefixes; renamed test/grader folders; building file lists programmatically with generic names.","solutions":["Include the problem ID in the uploaded file paths, e.g. name files 'taskname/graders/...' or ensure the identifiable component is present in a filename.","Inspect _prepare_files to see which filename patterns set potential_id and align your file naming with them.","Pass the problem ID explicitly if your client version supports it, or patch _prepare_files to accept data['problem_id'] as an override.","Add a pre-flight assertion that problem_id extraction succeeds before submitting the batch."],"exampleFix":"// before\nfiles = [{\"name\": \"main.cpp\", \"content\": code}]\n// after\nfiles = [{\"name\": \"tasks/collections/main.cpp\", \"content\": code}, {\"name\": \"tasks/collections/graders/grader.cpp\", \"content\": grader}]","handlingStrategy":"validation","validationCode":"def assert_problem_id_present(files):\n    import re\n    pattern = re.compile(r'(?:tasks?/)([A-Za-z0-9_-]+)/')\n    ok = any(pattern.search(f['name']) for f in files)\n    assert ok, 'No file path encodes the problem ID; fix file naming before submission'","typeGuard":"def files_have_problem_id(files: list) -> bool:\n    return any(f.get('name', '').startswith(('tasks/', 'graders/')) or '/' in f.get('name', '') for f in files)","tryCatchPattern":"try:\n    score, feedback = await client._execute_with_instance(instance, data)\nexcept ValueError as e:\n    if 'problem ID' in str(e):\n        logger.error('Upload layout invalid: %s — expected task-prefixed paths', [f['name'] for f in data['files']])\n    raise","preventionTips":["Adopt a fixed upload layout (tasks/<problem_id>/...) in your harness","Unit-test file-list construction for each problem package","Add an explicit problem_id override to avoid name inference entirely"],"tags":["morphcloud","configuration","problem-id"],"backgroundTag":"missing-identifier","analyzedSha":"1416fa0cf21595d2083b399a2a0bbddd7f6e9563","analyzedAt":"2026-08-30T08:56:53.400Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}