dotnet/runtime · error · RuntimeError

PMI not found at

Error message

PMI not found at {}

What it means

Raised by determine_pmi_location when the user explicitly passes --pmi_location but the resolved absolute path is not an existing file. pmi.dll is the SuperPMI private-method-invocation helper used for PMI-based collection/replay; the explicit path bypasses the PATH/Core_Root/download fallbacks, so a wrong path is a hard error.

Solutions

  1. Verify the path with 'ls <pmi_location>' and ensure it points to the pmi.dll/so file itself, not its parent directory.
  2. Drop --pmi_location to let the script find pmi.dll via PATH or Core_Root, or auto-download it from Azure Storage.
  3. Build pmi from the jitutils repo (https://github.com/dotnet/jitutils) if you need a local copy and confirm the output path.

Example fix

// before
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))
// after
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(f"PMI not found at {pmi_location}; pass the pmi.dll file path, or omit --pmi_location to auto-resolve")
Defensive patterns

Strategy: validation

Validate before calling

import os
def validate_pmi_location(pmi_location):
    if pmi_location is None:
        return None  # let auto-resolution handle it
    abs_path = os.path.abspath(pmi_location)
    if not os.path.isfile(abs_path):
        raise RuntimeError(f"--pmi_location is not a file: {abs_path}. Omit the flag to auto-resolve from PATH/Core_Root/download.")
    return abs_path

Prevention

When it happens

Trigger: Called during PMI workflow setup (coreclr_args.pmi is True): coreclr_args.pmi_location is not None, os.path.abspath is applied, then os.path.isfile(pmi_location) is False. Occurs when the --pmi_location value is a typo, a relative path resolved against an unexpected cwd, a directory rather than a file, or a file that was moved/deleted.

Common situations: Pointing --pmi_location at a build output that doesn't exist yet (PMI not built); passing the directory containing pmi.dll instead of the file path; stale path from a different machine or checkout.

Related errors


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

Appendix: 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 60108ba66e)