dotnet/runtime · error · RuntimeError
PMI not found at {}
Error message
PMI not found at {} What it means
Raised in `determine_pmi_location` (superpmi.py:3803-3804) when `-pmi_location` is supplied but does not point to an existing file. When the user explicitly names a pmi.dll, the script trusts that path and validates it exists rather than falling back to PATH/Core_Root/download.
Source
Thrown at src/coreclr/scripts/superpmi.py:3804
def determine_pmi_location(coreclr_args):
""" Determine pmi.dll location, using the following steps:
First, use the `-pmi_location` argument, if set.
Else, look for pmi.dll on the PATH. This will be true if you build jitutils yourself
and put the built `bin` directory on your PATH.
Else, look for pmi.dll in Core_Root. This is where we cache it if downloaded from Azure Storage
Otherwise, download a cached copy from CLRJIT Azure Storage and cache it in Core_Root.
Args:
coreclr_args (CoreclrArguments) : parsed args
Returns:
pmi_location (str) : path of pmi.dll
"""
if coreclr_args.pmi_location is not None:
pmi_location = os.path.abspath(coreclr_args.pmi_location)
if not os.path.isfile(pmi_location):
raise RuntimeError("PMI not found at {}".format(pmi_location))
logging.info("Using PMI at %s", pmi_location)
else:
path_var = os.environ.get("PATH")
pmi_location = find_file("pmi.dll", path_var.split(os.pathsep)) if path_var is not None else None
if pmi_location is not None:
logging.info("Using PMI found on PATH at %s", pmi_location)
else:
pmi_location = os.path.join(coreclr_args.core_root, "pmi.dll")
if os.path.isfile(pmi_location):
logging.info("Using PMI found at %s", pmi_location)
else:
pmi_uri = az_blob_storage_superpmi_container_uri + "/pmi/pmi.dll"
skip_progress = hasattr(coreclr_args, 'no_progress') and coreclr_args.no_progress
download_one_url(pmi_uri, pmi_location, is_azure_storage=True, display_progress=not skip_progress)
assert os.path.isfile(pmi_location)
return pmi_location
View on GitHub (pinned to 290d5ab72c)
Solutions
- Verify the path with `ls <path>` and correct typos; use an absolute path to the pmi.dll.
- Drop `-pmi_location` entirely to let the script find pmi.dll on PATH, in Core_Root, or download it from Azure Storage.
- Rebuild/restore pmi.dll (from the jitutils repo) if the file is genuinely missing.
Example fix
// before superpmi.py collect --pmi -pmi_location ./bin/pmi.dll -assemblies Foo // after superpmi.py collect --pmi -pmi_location /abs/path/to/jitutils/bin/pmi.dll -assemblies Foo
Defensive patterns
Strategy: validation
Validate before calling
import os
if args.pmi_location is not None:
pmi = os.path.abspath(args.pmi_location)
if not os.path.isfile(pmi):
raise SystemExit(f'-pmi_location {pmi} is not a file; omit the flag to auto-resolve/download pmi.dll') Prevention
- Use absolute paths for -pmi_location.
- Omit -pmi_location to let the script find or download pmi.dll.
When it happens
Trigger: Passing `-pmi_location <path>` to the collect subcommand where the path does not exist on disk. The check is an os.path.isfile on the absolute path before any fallback logic.
Common situations: Typo in the path; pointing at a stale pmi.dll from a removed build; relative path that resolves wrong under a different cwd; passing a directory instead of the dll file.
Related errors
- Tiering options have no effect for pmi or crossgen2 collecti
- Pass only one tiering option.
- Expected a '.ilc.rsp' file for nativeaot, but got {original_
- Unable to find input file in {original_rsp_filepath}
- No .mc files generated.
AI-assisted analysis of dotnet/runtime@290d5ab72c (2026-08-06).
Data as JSON: /api/errors/b2f7c4ea21424e06.
Report an issue: GitHub.