LykosAI/StabilityMatrix · error · FileNotFoundException

pip not found

Error message

pip not found

What it means

PyRunner.InstallPackage installs a pip package by shelling out to pip. It checks installation.PipExePath exists first; if the pip executable is missing, a FileNotFoundException with the path is thrown.

Solutions

  1. Run SetupPip (or 'python -m ensurepip') on the installation to install pip first
  2. Verify installation.PipExePath exists before installing packages
  3. Recreate the venv/environment ensuring pip is included (virtualenv with pip, not --without-pip)
  4. Alternatively invoke 'python -m pip install' via the Python executable as a fallback

Example fix

// before
await pyRunner.InstallPackage(installation, "numpy"); // pip missing
// after
if (!File.Exists(installation.PipExePath))
    await pyRunner.SetupPip(installation);
await pyRunner.InstallPackage(installation, "numpy");
Defensive patterns

Strategy: validation

Validate before calling

if (!File.Exists(installation.PipExePath))
    await pyRunner.SetupPip(installation);

Try / catch

try
{
    await pyRunner.InstallPackage(installation, packageName);
}
catch (FileNotFoundException ex)
{
    logger.LogError(ex, "pip missing; bootstrapping");
    await pyRunner.SetupPip(installation);
    await pyRunner.InstallPackage(installation, packageName);
}

Prevention

When it happens

Trigger: Calling InstallPackage on an installation where pip was never installed (SetupPip not run), a venv without pip, or a corrupted environment missing the pip executable.

Common situations: Fresh environments created with pip omitted, environments where pip was uninstalled, custom Python distributions without pip, install metadata pointing at a stale PipExePath.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


AI-assisted analysis of LykosAI/StabilityMatrix@af93d6ef57 (2026-09-12). Data as JSON: /api/errors/ec0ac1db6aa0b50c. Report an issue: GitHub.

Appendix: source

Thrown at StabilityMatrix.Core/Python/PyRunner.cs:295

            .EnsureSuccessExitCode()
            .ConfigureAwait(false);
    }

    /// <summary>
    /// Install a Python package with pip
    /// </summary>
    public async Task InstallPackage(string package, PyVersion? version = null)
    {
        // Use either the specified version or the current installation
        var installation =
            version != null
                ? await installationManager.GetInstallationAsync(version.Value).ConfigureAwait(false)
                : currentInstallation
                    ?? await installationManager.GetDefaultInstallationAsync().ConfigureAwait(false);

        if (!File.Exists(installation.PipExePath))
        {
            throw new FileNotFoundException("pip not found", installation.PipExePath);
        }
        var result = await ProcessRunner
            .GetProcessResultAsync(installation.PythonExePath, $"-m pip install {package}")
            .ConfigureAwait(false);
        result.EnsureSuccessExitCode();
    }

    /// <summary>
    /// Run a Function with PyRunning lock as a Task with GIL.
    /// </summary>
    /// <param name="func">Function to run.</param>
    /// <param name="waitTimeout">Time limit for waiting on PyRunning lock.</param>
    /// <param name="cancelToken">Cancellation token.</param>
    /// <exception cref="OperationCanceledException">cancelToken was canceled, or waitTimeout expired.</exception>
    public async Task<T> RunInThreadWithLock<T>(
        Func<T> func,
        TimeSpan? waitTimeout = null,
        CancellationToken cancelToken = default

View on GitHub (pinned to af93d6ef57)