dotnet/runtime · error · RuntimeError

Tool {tool_name} not found. Have you built the runtime repo

Error message

Tool {tool_name} not found. Have you built the runtime repo and created a Core_Root, or put it on your PATH?

What it means

Raised in `find_tool` (superpmi.py:3881-3882) when throw_on_not_found is True and a required tool (superpmi, mcs, dotnet, etc.) was not found in Core_Root, the product build location, or on PATH. The tool must exist somewhere discoverable for the script to invoke it.

Source

Thrown at src/coreclr/scripts/superpmi.py:3882

    # Next, look in the built product directory, if it exists. We can use superpmi/mcs directly from the
    # product build directory instead from Core_Root because they don't depend on managed code libraries.
    if search_product_location and hasattr(coreclr_args, "product_location") and coreclr_args.product_location is not None and os.path.isdir(coreclr_args.product_location):
        tool_path = os.path.join(coreclr_args.product_location, tool_name)
        if os.path.isfile(tool_path):
            logging.debug("Using %s from product build location: %s", tool_name, tool_path)
            return tool_path

    # Finally, look on the PATH
    if search_path:
        path_var = os.environ.get("PATH")
        if path_var is not None:
            tool_path = find_file(tool_name, path_var.split(os.pathsep))
            if tool_path is not None:
                logging.debug("Using %s from PATH: %s", tool_name, tool_path)
                return tool_path

    if throw_on_not_found:
        raise RuntimeError("Tool " + tool_name + " not found. Have you built the runtime repo and created a Core_Root, or put it on your PATH?")

    return None


def determine_superpmi_tool_name(coreclr_args):
    """ Determine the superpmi tool name based on the OS

    Args:
        coreclr_args (CoreclrArguments): parsed args

    Return:
        (str) Name of the superpmi tool to use
    """

    if coreclr_args.host_os == "osx" or coreclr_args.host_os == "linux":
        return "superpmi"
    elif coreclr_args.host_os == "windows":
        return "superpmi.exe"

View on GitHub (pinned to 290d5ab72c)

Solutions

  1. Build the runtime repo and create a Core_Root (the build emits superpmi/mcs), then re-run.
  2. Build jitutils and add its `bin` directory to PATH so the tools resolve.
  3. Pass `-core_root` / `-product_location` pointing at a location that already contains the tool.

Example fix

// before
superpmi.py replay -mch_files foo.mch ...   # nothing built yet
// after
# build runtime first, then:
superpmi.py replay -core_root artifacts/bin/coreclr/<os>.<arch>.Release -mch_files foo.mch ...
Defensive patterns

Strategy: validation

Validate before calling

import shutil
def tool_available(name, core_root=None):
    if core_root and os.path.isfile(os.path.join(core_root, name)):
        return True
    return shutil.which(name) is not None
for t in ('superpmi', 'mcs'):
    if not tool_available(t, coreclr_args.core_root):
        raise SystemExit(f'{t} not found; build the runtime/Core_Root or add jitutils bin to PATH.')

Prevention

When it happens

Trigger: Any flow that calls find_tool with throw_on_not_found=True when the named binary is absent from all three search locations. E.g. running replay/asmdiffs without having built the runtime or put superpmi/mcs on PATH.

Common situations: Fresh clone where the runtime hasn't been built; a build that didn't produce Core_Root; PATH not including the jitutils `bin` directory; building only a subset of components so the tool wasn't emitted.

Related errors


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