dotnet/runtime · error · RuntimeError
Pass only one tiering option.
Error message
Pass only one tiering option.
What it means
Raised in SuperPMICollection.__init__ (superpmi.py:725-726) when both --tiered_compilation and --tiered_pgo are passed to the `collect` subcommand. The flags are treated as mutually exclusive because --tiered_pgo already sets DOTNET_TieredCompilation=1 in addition to DOTNET_TieredPGO=1, so specifying both is redundant and ambiguous. This is a runtime guard, not an argparse mutually_exclusive_group, so argparse will not catch it earlier.
Source
Thrown at src/coreclr/scripts/superpmi.py:726
self.corerun = os.path.join(self.core_root, self.corerun_tool_name)
if coreclr_args.crossgen2:
self.corerun = os.path.join(self.core_root, self.corerun_tool_name)
if coreclr_args.pmi or coreclr_args.crossgen2:
self.assemblies = coreclr_args.assemblies
self.exclude = coreclr_args.exclude
if coreclr_args.tiered_compilation or coreclr_args.tiered_pgo:
raise RuntimeError("Tiering options have no effect for pmi or crossgen2 collections.")
if coreclr_args.nativeaot:
self.ilc_rsps = coreclr_args.ilc_rsps
self.exclude = coreclr_args.exclude
if coreclr_args.tiered_compilation or coreclr_args.tiered_pgo:
raise RuntimeError("Tiering options have no effect for nativeaot collections.")
if coreclr_args.tiered_compilation and coreclr_args.tiered_pgo:
raise RuntimeError("Pass only one tiering option.")
self.coreclr_args = coreclr_args
self.temp_location = None
# Pathname for a temporary .MCL file used for noticing SuperPMI replay failures against base MCH.
self.base_fail_mcl_file = None
# The base .MCH file path
self.base_mch_file = None
# Final .MCH file path
if self.coreclr_args.output_mch_path is not None:
self.final_mch_file = os.path.abspath(self.coreclr_args.output_mch_path)
final_mch_dir = os.path.dirname(self.final_mch_file)
if not os.path.isdir(final_mch_dir):
os.makedirs(final_mch_dir)
else:View on GitHub (pinned to 290d5ab72c)
Solutions
- Remove --tiered_compilation and keep only --tiered_pgo (it enables both DOTNET_TieredCompilation=1 and DOTNET_TieredPGO=1).
- If you only want tiered compilation without PGO, drop --tiered_pgo and keep --tiered_compilation alone.
- Fix the script/matrix that assembles the CLI args to treat the two flags as mutually exclusive.
Example fix
// before superpmi.py collect --crossgen2 -assemblies Foo --tiered_compilation --tiered_pgo // after superpmi.py collect --crossgen2 -assemblies Foo --tiered_pgo
Defensive patterns
Strategy: validation
Validate before calling
# Before invoking superpmi collect, reject the conflicting combination
import sys
tiered_compilation = '--tiered_compilation' in sys.argv
tiered_pgo = '--tiered_pgo' in sys.argv
if tiered_compilation and tiered_pgo:
raise SystemExit('Use only one of --tiered_compilation / --tiered_pgo (tiered_pgo implies tiered_compilation).')
# ...then launch superpmi.py Prevention
- Treat --tiered_compilation and --tiered_pgo as mutually exclusive in any wrapper/matrix that builds the command line.
- Remember --tiered_pgo already sets DOTNET_TieredCompilation=1.
When it happens
Trigger: Running `superpmi.py collect ... --tiered_compilation --tiered_pgo ...`. Both are `store_true` flags with no argparse choices restriction, so the command parses successfully and the check in __init__ is what rejects it.
Common situations: Starting from a tiered-compilation collection command and appending --tiered_pgo to enable PGO without dropping the first flag; matrix/CI scripts that toggle the two flags from independent variables and accidentally set both to true.
Related errors
- Invalid summary_type: {coreclr_args.summary_type}
- Specified -base_jit_path does not point to a file
- Tiering options have no effect for pmi or crossgen2 collecti
- Tiering options have no effect for nativeaot collections.
- Expected a '.ilc.rsp' file for nativeaot, but got {original_
AI-assisted analysis of dotnet/runtime@290d5ab72c (2026-08-06).
Data as JSON: /api/errors/b5957df24715acf7.
Report an issue: GitHub.