{"record":{"id":"c2eb3651a63aa3bb","repo":"dotnet/runtime","slug":"expected-a-ilc-rsp-file-for-nativeaot-but-got","errorCode":null,"errorMessage":"Expected a '.ilc.rsp' file for nativeaot, but got {original_rsp_filepath}","messagePattern":"Expected a '\\.ilc\\.rsp' file for nativeaot, but got (.+?)","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"src/coreclr/scripts/superpmi.py","lineNumber":1189,"sourceCode":"                # Note: crossgen2 compiles in parallel by default. However, it seems to lead to sharing violations\n                # in SuperPMI collection, accessing the MC file. So, disable crossgen2 parallism by using\n                # the \"--parallelism:1\" switch, and allowing coarse-grained (per-assembly) parallelism here.\n                # It turns out this works better anyway, as there is a lot of non-parallel time between\n                # crossgen2 parallel compilations.\n                helper = AsyncSubprocessHelper(assemblies, verbose=True)\n                helper.run_to_completion(run_crossgen2, self)\n\n                os.environ.clear()\n                os.environ.update(old_env)\n            ################################################################################################ end of \"self.coreclr_args.crossgen2 is True\"\n\n            ################################################################################################ Do collection using nativeaot\n            if self.coreclr_args.nativeaot is True:\n                logging.debug(\"Starting collection using nativeaot\")\n\n                async def run_nativeaot(print_prefix, original_rsp_filepath, self):\n                    if not original_rsp_filepath.endswith(\".ilc.rsp\"):\n                        raise RuntimeError(f\"Expected a '.ilc.rsp' file for nativeaot, but got {original_rsp_filepath}\")\n\n                    # The contents of the rsp contain many knobs and arguments that represent customer scenarios.\n                    # Make a copy of the .ilc.rsp file as we are going to modify it. We do not want to modify the original one.\n                    # The modifications include re-writing paths for references, input assembly and the output.\n                    # We do this because the current paths in the rsp *may* not exist by the time we want to run ilc.\n                    rsp_filepath = os.path.join(self.temp_location, make_safe_filename(\"nativeaot_\" + original_rsp_filepath) + \".rsp\")\n                    shutil.copyfile(original_rsp_filepath, rsp_filepath)\n\n                    rsp_file = open(rsp_filepath, \"r\")\n                    rsp_contents = rsp_file.readlines()\n                    rsp_file.close()\n\n                    original_input_filepath = \"\"\n\n                    for line in rsp_contents:\n                        if not line.startswith(\"-\"):\n                            original_input_filepath = line\n","sourceCodeStart":1171,"sourceCodeEnd":1207,"githubUrl":"https://github.com/dotnet/runtime/blob/290d5ab72cc1102813fbc0406fb186ceadabc340/src/coreclr/scripts/superpmi.py#L1171-L1207","documentation":"Raised inside the async `run_nativeaot` worker (superpmi.py:1187-1189) during a nativeaot collection. Every entry passed via `-ilc_rsps` must be an ILC response file whose name ends in `.ilc.rsp`; anything else is rejected before the rsp is parsed and rewritten. The collection only understands native AOT ilc.rsp inputs, so a different file type cannot be processed.","triggerScenarios":"Invoking `superpmi.py collect --nativeaot -ilc_rsps <path>` where one of the supplied paths does not end with `.ilc.rsp` (e.g. a directory, a `.dll`, a `.csproj`, or a generic `.rsp`). The AsyncSubprocessHelper dispatches each path to run_nativeaot, which fails on the first non-matching path.","commonSituations":"Passing a parent directory or a glob expansion that includes non-rsp files to `-ilc_rsps`; pointing at a plain crossgen2/csc response file instead of the ILC-generated `.ilc.rsp`; typo in the filename extension.","solutions":["Ensure every path in `-ilc_rsps` is an actual `*.ilc.rsp` file produced by the native AOT build.","If you passed a directory, enumerate its `.ilc.rsp` files and pass those explicit paths.","Filter the list with a shell glob like `-ilc_rsps path/**/*.ilc.rsp` to exclude unrelated files."],"exampleFix":"// before\nsuperpmi.py collect --nativeaot -ilc_rsps tests/ComWrappers/native/ComWrappers.csproj\n// after\nsuperpmi.py collect --nativeaot -ilc_rsps tests/ComWrappers/native/ComWrappers.ilc.rsp","handlingStrategy":"validation","validationCode":"# Validate ilc_rsp inputs before launching the nativeaot collection\nilc_rsps = [p for p in args.ilc_rsps]\nbad = [p for p in ilc_rsps if not p.endswith('.ilc.rsp')]\nif bad:\n    raise SystemExit('All -ilc_rsps entries must end in .ilc.rsp; offending: ' + ', '.join(bad))","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Glob with **/*.ilc.rsp instead of passing directories.","Reject non-.ilc.rsp paths in the wrapper before invoking superpmi."],"tags":["nativeaot","args","file-io","superpmi"],"analyzedSha":"290d5ab72cc1102813fbc0406fb186ceadabc340","analyzedAt":"2026-08-06T19:57:01.276Z","schemaVersion":2},"datasetVersion":"2026-08-06T23:17:07.152Z"}