dotnet/BenchmarkDotNet · error · InvalidOperationException

Unable to get value of 'ConsoleRunnerPackage'.

Error message

Unable to get value of 'ConsoleRunnerPackage'.

What it means

GetRunnerPath found the 'ConsoleRunnerPackage' field but its value is null. The field exists but DotMemory.InitAsync has not populated it (or populated and then reset it). This is the second guard in the reflection chain used to locate the dotMemory runner executable.

Source

Thrown at src/BenchmarkDotNet.Diagnostics.dotMemory/DotMemoryDiagnoser.cs:56

    protected override void Detach()
    {
        DotMemory.Detach();
    }

    protected override string CreateSnapshotFilePath(DiagnoserActionParameters parameters)
    {
        return ArtifactFileNameHelper.GetFilePath(parameters, "snapshots", DateTime.Now, "dmw", ".0000".Length);
    }

    protected override string GetRunnerPath()
    {
        var consoleRunnerPackageField = typeof(DotMemory).GetField("ConsoleRunnerPackage", BindingFlags.NonPublic | BindingFlags.Static);
        if (consoleRunnerPackageField == null)
            throw new InvalidOperationException("Field 'ConsoleRunnerPackage' not found.");

        object? consoleRunnerPackage = consoleRunnerPackageField.GetValue(null);
        if (consoleRunnerPackage == null)
            throw new InvalidOperationException("Unable to get value of 'ConsoleRunnerPackage'.");

        var consoleRunnerPackageType = consoleRunnerPackage.GetType();
        var getRunnerPathMethod = consoleRunnerPackageType.GetMethod("GetRunnerPath");
        if (getRunnerPathMethod == null)
            throw new InvalidOperationException("Method 'GetRunnerPath' not found.");

        string? runnerPath = getRunnerPathMethod.Invoke(consoleRunnerPackage, null) as string;
        if (runnerPath == null)
            throw new InvalidOperationException("Unable to invoke 'GetRunnerPath'.");

        return runnerPath;
    }

    internal override bool IsSupported(RuntimeMoniker runtimeMoniker)
    {
        switch (runtimeMoniker)
        {
            case RuntimeMoniker.HostProcess:

View on GitHub (pinned to b515068b61)

Solutions

  1. Ensure InitTool completes fully before GetRunnerPath is invoked (SnapshotProfilerBase.Init does this in order).
  2. Clear the cached dotMemory prerequisite and let InitAsync re-download it.
  3. Align the JetBrains.Profiler.SelfApi version with the BenchmarkDotNet build.
Defensive patterns

Strategy: fallback

Try / catch

try { /* use dotMemory diagnoser */ }
catch (InvalidOperationException ex) when (ex.Message.Contains("Unable to get value of 'ConsoleRunnerPackage'"))
{
    log.Error("dotMemory prerequisite not initialized; clear cache and let InitAsync re-download.");
}

Prevention

When it happens

Trigger: InitTool (DotMemory.InitAsync) returned without error but never assigned the static ConsoleRunnerPackage instance; or it was assigned and later nulled (e.g. partial/failed prerequisite install that reported success, or a SelfApi version that lazily populates the field).

Common situations: InitAsync succeeded against a corrupted prerequisite download; running Init concurrently or calling GetRunnerPath before Init has fully populated state; a SelfApi build that defers package instantiation.

Related errors


AI-assisted analysis of dotnet/BenchmarkDotNet@b515068b61 (2026-08-13). Data as JSON: /api/errors/c9f77f1340f7a948. Report an issue: GitHub.