dotnet/runtime · error · RuntimeError

Final mch file failed to be generated.

Error message

Final mch file failed to be generated.

What it means

Raised by SuperPMICollect.__create_clean_mch_file__ in superpmi.py after the clean step. Depending on whether base_fail_mcl_file is non-empty it either runs `mcs -strip` or copies base.mch to final_mch_file; then it asserts os.path.isfile(self.final_mch_file) and raises if the final MCH is missing.

Solutions

  1. Re-run with -log_level debug and inspect the superpmi/mcs commands run during the clean step.
  2. Ensure the output directory (-output_mch_path parent, or cwd) exists and is writable with enough disk space.
  3. Verify base.mch existed before the clean step (i.e. the prior merge succeeded); if not, fix the merge first.
  4. Drop --clean to fall back to the copy path (__copy_to_final_mch_file__) and confirm output is produced.

Example fix

// before
python superpmi.py collect 'cmd' --clean   # strip/copy failed -> 'Final mch file failed to be generated.'
// after
python superpmi.py collect 'cmd' --clean -log_level debug   # inspect, free disk / fix mcs, then re-run
Defensive patterns

Strategy: validation

Validate before calling

import os
if not os.path.isfile(final_mch_file):
    raise SystemExit(f"Final MCH not generated at {final_mch_file}; ensure disk space, permissions, and a valid base.mch")

Prevention

When it happens

Trigger: Running `superpmi.py collect ... --clean` where the strip step failed or the shutil.copy2 of base.mch to the final path failed, leaving final_mch_file absent.

Common situations: mcs -strip failed on the failure MCL; out of disk space; the final_mch_file directory was removed mid-run; permission error on the output path; base.mch itself was missing going into the copy.

Related errors


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

Appendix: source

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

            else
                # copy/move base file to final file
            del <s_baseFailMclFile>
        """

        logging.info("Cleaning MCH file")

        command = [self.superpmi_path, "-p", "-f", self.base_fail_mcl_file, self.base_mch_file, self.jit_path]
        run_and_log(command)

        if is_nonzero_length_file(self.base_fail_mcl_file):
            command = [self.mcs_path, "-strip", self.base_fail_mcl_file, self.base_mch_file, self.final_mch_file]
            run_and_log(command)
        else:
            # Ideally we could just rename this file instead of copying it.
            shutil.copy2(self.base_mch_file, self.final_mch_file)

        if not os.path.isfile(self.final_mch_file):
            raise RuntimeError("Final mch file failed to be generated.")

        if not self.coreclr_args.skip_cleanup:
            if os.path.isfile(self.base_fail_mcl_file):
                os.remove(self.base_fail_mcl_file)
                self.base_fail_mcl_file = None
            if os.path.isfile(self.base_mch_file):
                os.remove(self.base_mch_file)
                self.base_mch_file = None

    def __copy_to_final_mch_file__(self):
        """ When not cleaning the MCH file, copy the base MCH file to the final MCH file location.

        Notes:
            # copy/move base file to final file
            del <s_baseFailMclFile>
        """

        logging.info("Copy base MCH file to final MCH file")

View on GitHub (pinned to 60108ba66e)