dotnet/runtime · error · RuntimeError

Expected a '.ilc.rsp' file for nativeaot, but got

Error message

Expected a '.ilc.rsp' file for nativeaot, but got {original_rsp_filepath}

What it means

Raised inside run_nativeaot() in superpmi.py when an rsp file passed to the nativeaot collector does not end with '.ilc.rsp'. NativeAOT collection parses ilc response files; a differently-named file is a programming/usage error.

Solutions

  1. Ensure every file passed via -ilc_rsps ends with '.ilc.rsp' (e.g. ComWrappers.ilc.rsp).
  2. Regenerate the ilc.rsp via the normal nativeaot build if the rsp is missing or mis-named.
  3. Use -exclude to filter out stray non-rsp files when pointing -ilc_rsps at a directory.

Example fix

// before
python superpmi.py collect --nativeaot -ilc_rsps ComWrappers.rsp   # 'Expected a .ilc.rsp file ... but got ComWrappers.rsp'
// after
python superpmi.py collect --nativeaot -ilc_rsps ComWrappers/native/ComWrappers.ilc.rsp
Defensive patterns

Strategy: validation

Validate before calling

bad = [p for p in ilc_rsps if not p.endswith(".ilc.rsp")]
if bad:
    raise SystemExit("All -ilc_rsps files must end with '.ilc.rsp'; offending: " + ", ".join(bad))

Type guard

def is_ilc_rsp(path: str) -> bool:
    return path.endswith(".ilc.rsp")

Prevention

When it happens

Trigger: Passing a non-.ilc.rsp file via -ilc_rsps (or a directory whose filtered contents include a stray non-rsp file), so original_rsp_filepath does not end with '.ilc.rsp'.

Common situations: Pointing -ilc_rsps at a .rsp without the 'ilc.' prefix; a stale/mis-generated rsp; directory globs picking up unrelated files.

Related errors


AI-assisted analysis of dotnet/runtime@60108ba66e (2026-08-10). Data as JSON: /api/errors/c2eb3651a63aa3bb. Report an issue: GitHub.

Appendix: source

Thrown at src/coreclr/scripts/superpmi.py:1189

                # Note: crossgen2 compiles in parallel by default. However, it seems to lead to sharing violations
                # in SuperPMI collection, accessing the MC file. So, disable crossgen2 parallism by using
                # the "--parallelism:1" switch, and allowing coarse-grained (per-assembly) parallelism here.
                # It turns out this works better anyway, as there is a lot of non-parallel time between
                # crossgen2 parallel compilations.
                helper = AsyncSubprocessHelper(assemblies, verbose=True)
                helper.run_to_completion(run_crossgen2, self)

                os.environ.clear()
                os.environ.update(old_env)
            ################################################################################################ end of "self.coreclr_args.crossgen2 is True"

            ################################################################################################ Do collection using nativeaot
            if self.coreclr_args.nativeaot is True:
                logging.debug("Starting collection using nativeaot")

                async def run_nativeaot(print_prefix, original_rsp_filepath, self):
                    if not original_rsp_filepath.endswith(".ilc.rsp"):
                        raise RuntimeError(f"Expected a '.ilc.rsp' file for nativeaot, but got {original_rsp_filepath}")

                    # The contents of the rsp contain many knobs and arguments that represent customer scenarios.
                    # Make a copy of the .ilc.rsp file as we are going to modify it. We do not want to modify the original one.
                    # The modifications include re-writing paths for references, input assembly and the output.
                    # We do this because the current paths in the rsp *may* not exist by the time we want to run ilc.
                    rsp_filepath = os.path.join(self.temp_location, make_safe_filename("nativeaot_" + original_rsp_filepath) + ".rsp")
                    shutil.copyfile(original_rsp_filepath, rsp_filepath)

                    rsp_file = open(rsp_filepath, "r")
                    rsp_contents = rsp_file.readlines()
                    rsp_file.close()

                    original_input_filepath = ""

                    for line in rsp_contents:
                        if not line.startswith("-"):
                            original_input_filepath = line

View on GitHub (pinned to 60108ba66e)