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

  1. Verify the path with `ls <path>` and correct typos; use an absolute path to the pmi.dll.
  2. Drop `-pmi_location` entirely to let the script find pmi.dll on PATH, in Core_Root, or download it from Azure Storage.
  3. 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

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


AI-assisted analysis of dotnet/runtime@290d5ab72c (2026-08-06). Data as JSON: /api/errors/b2f7c4ea21424e06. Report an issue: GitHub.