{"record":{"id":"7229d7e8f2d2beed","repo":"dotnet/runtime","slug":"error-unclean-replay","errorCode":null,"errorMessage":"Error, unclean replay.","messagePattern":"Error, unclean replay\\.","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"src/coreclr/scripts/superpmi.py","lineNumber":1479,"sourceCode":"\n        if not os.path.isfile(self.toc_file):\n            raise RuntimeError(\"Error, toc file not created correctly at: %s\" % self.toc_file)\n\n    def __verify_final_mch__(self):\n        \"\"\" Verify the resulting MCH file is error-free when running SuperPMI against it with the same JIT used for collection.\n\n        Notes:\n            <SuperPmiPath> -p -f <s_finalFailMclFile> <s_finalMchFile> <jitPath>\n        \"\"\"\n\n        logging.info(\"Verifying MCH file\")\n\n        mch_files = [ self.final_mch_file ]\n        spmi_replay = SuperPMIReplay(self.coreclr_args, mch_files, self.jit_path)\n        passed = spmi_replay.replay()\n\n        if not passed:\n            raise RuntimeError(\"Error, unclean replay.\")\n\n    def __process_for_ci__(self):\n        \"\"\" Helix doesn't upload zero-sized files. Sometimes we end up with zero-sized .mch files if\n            there is no data collected. Convert these to special \"sentinel\" files that are later processed\n            by \"merge-mch\" by deleting them. This prevents the <HelixWorkItem.DownloadFilesFromResults>\n            file download to succeed (because the file exists) and the MCH merge to also succeed.\n        \"\"\"\n\n        logging.info(\"Process MCH files for CI\")\n\n        if os.path.getsize(self.final_mch_file) == 0:\n            # Convert to sentinel file\n            logging.info(\"Converting zero-length MCH file {} to ZEROLENGTH sentinel file\".format(self.final_mch_file))\n            with open(self.final_mch_file, \"w\") as write_fh:\n                write_fh.write(\"ZEROLENGTH\")\n\n################################################################################\n# SuperPMI Replay helpers","sourceCodeStart":1461,"sourceCodeEnd":1497,"githubUrl":"https://github.com/dotnet/runtime/blob/290d5ab72cc1102813fbc0406fb186ceadabc340/src/coreclr/scripts/superpmi.py#L1461-L1497","documentation":"Raised in `__verify_final_mch__` (superpmi.py:1478-1479), only reached when `--clean` is set. After cleaning, it replays the final MCH against the same JIT used for collection; if SuperPMIReplay.replay() returns False (any context failed), the collection is considered non-deterministic/unclean and rejected. A clean collection must replay every context error-free.","triggerScenarios":"Collecting with `--clean` where the verification replay of the final MCH with the collection JIT reports at least one failing context. This indicates the JIT did not deterministically reproduce some captured method contexts.","commonSituations":"Non-deterministic JIT behavior (e.g. randomness/tiering leaking in), time- or thread-dependent compilations, an MCH that still contains contexts that fail to replay after stripping, or using a JIT build that differs subtly from the collection-time JIT.","solutions":["Re-run the collection with `--clean` (it strips failing contexts) until replay passes; if it never passes, investigate the failing context reported by the replay.","Ensure tiering is explicitly controlled (--tiered_compilation / --tiered_pgo) so collection is deterministic.","Confirm the JIT used for the verification replay is the same clrjit used during collection (same Core_Root/build)."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"# Best-effort: ensure deterministic collection env before clean+verify\n# (determinism is enforced via DOTNET_ vars; nothing to validate offline)\npass","typeGuard":null,"tryCatchPattern":"attempt = 0\npassed = False\nwhile not passed and attempt < 3:\n    attempt += 1\n    try:\n        collection.__verify_final_mch__()\n        passed = True\n    except RuntimeError as e:\n        if 'unclean replay' not in str(e):\n            raise\n        logging.warning('unclean replay on attempt %d; re-running clean', attempt)\n        collection.__create_clean_mch_file__()  # strip more failing contexts\nif not passed:\n    raise SystemExit('MCH never replayed cleanly after retries')","preventionTips":["Pin tiering state (--tiered_compilation / --tiered_pgo) for determinism.","Use the same clrjit for collection and verification."],"tags":["mch","replay","clean","superpmi","diagnostics"],"analyzedSha":"290d5ab72cc1102813fbc0406fb186ceadabc340","analyzedAt":"2026-08-06T19:57:01.276Z","schemaVersion":2},"datasetVersion":"2026-08-06T23:17:07.152Z"}