dotnet/BenchmarkDotNet · error · ArgumentOutOfRangeException

Runtime not supported

Error message

Runtime not supported

What it means

Thrown by the public GetToolchain(Runtime runtime, ...) overload when the runtime object's concrete type is none of the six handled switch cases (ClrRuntime, MonoRuntime, CoreRuntime, NativeAotRuntime, WasmRuntime, R2RRuntime). BDN dispatches toolchain selection by runtime type, and any unrecognized type — including custom Runtime subclasses or null in some edge paths — falls through to the default and raises ArgumentOutOfRangeException. This is reached only when no explicit toolchain is set on the Job (otherwise TryGetToolchain short-circuits).

Source

Thrown at src/BenchmarkDotNet/Toolchains/ToolchainExtensions.cs:113

                    return CsProjCoreToolchain.From(new NetCoreAppSettings(coreRuntime.MsBuildMoniker, coreRuntime.Name));

                case NativeAotRuntime nativeAotRuntime:
                    return nativeAotRuntime.RuntimeMoniker != RuntimeMoniker.NotRecognized
                            ? GetToolchain(nativeAotRuntime.RuntimeMoniker)
                            : NativeAotToolchain.CreateBuilder().UseNuGet().TargetFrameworkMoniker(nativeAotRuntime.MsBuildMoniker).ToToolchain();

                case WasmRuntime wasmRuntime:
                    return WasmToolchain.From(new NetCoreAppSettings(targetFrameworkMoniker: wasmRuntime.MsBuildMoniker, name: wasmRuntime.Name));

                case R2RRuntime r2rRuntime:
                    if (r2rRuntime.RuntimeMoniker != RuntimeMoniker.NotRecognized)
                        return GetToolchain(r2rRuntime.RuntimeMoniker);

                    return CsProjCoreToolchain.From(new NetCoreAppSettings(r2rRuntime.MsBuildMoniker, r2rRuntime.Name));

                default:
                    throw new ArgumentOutOfRangeException(nameof(runtime), runtime, "Runtime not supported");
            }
        }

        private static IToolchain GetToolchain(RuntimeMoniker runtimeMoniker)
        {
            switch (runtimeMoniker)
            {
                case RuntimeMoniker.Net461:
                    return CsProjClassicNetToolchain.Net461;

                case RuntimeMoniker.Net462:
                    return CsProjClassicNetToolchain.Net462;

                case RuntimeMoniker.Net47:
                    return CsProjClassicNetToolchain.Net47;

                case RuntimeMoniker.Net471:
                    return CsProjClassicNetToolchain.Net471;

View on GitHub (pinned to b515068b61)

Solutions

  1. Provide an explicit toolchain on the Job via .WithToolchain(yourToolchain) so GetToolchain never dispatches by runtime type (TryGetToolchain short-circuits at line 22/32)
  2. Use one of the built-in Runtime types (CoreRuntime, ClrRuntime, MonoRuntime, NativeAotRuntime, WasmRuntime, R2RRuntime) instead of a custom subclass
  3. If you need a custom runtime, upgrade/align BDN to a version where your runtime type is handled, or contribute a case to the switch

Example fix

// before
public class MyCustomRuntime : Runtime { /* ... */ }

var job = Job.Default.WithRuntime(new MyCustomRuntime());
// => ArgumentOutOfRangeException: Runtime not supported

// after (explicit toolchain — recommended for custom runtimes)
var job = Job.Default
    .WithRuntime(new MyCustomRuntime())
    .WithToolchain(CsProjCoreToolchain.From(
        new NetCoreAppSettings("net8.0", "MyCustom")));
Defensive patterns

Strategy: type-guard

Type guard

// Guard the runtime before BDN dispatches a toolchain by type.
using BenchmarkDotNet.Environments;

static bool IsKnownRuntime(Runtime? r) => r is ClrRuntime or CoreRuntime or MonoRuntime
    or NativeAotRuntime or WasmRuntime or R2RRuntime;

if (!IsKnownRuntime(job.ResolveValue(EnvironmentMode.RuntimeCharacteristic, EnvironmentResolver.Instance)))
    throw new InvalidOperationException(
        "Runtime type is not handled by BDN's toolchain dispatcher; set an explicit toolchain via .WithToolchain(...).");

Try / catch

try { BenchmarkRunner.Run<MyBench>(); }
catch (ArgumentOutOfRangeException ex) when (ex.Message.Contains("Runtime not supported"))
{
    throw new InvalidOperationException(
        "The configured Runtime type has no built-in toolchain. Set one explicitly with .WithToolchain(...).", ex);
}

Prevention

When it happens

Trigger: ToolchainExtensions.GetToolchain(Runtime, Descriptor?, bool, bool) is called for a BenchmarkCase or Job whose Runtime is a type outside the six known types. Entry points: benchmarkCase.GetToolchain() (line 21) and job.GetToolchain() (line 31), both of which only call this when the Job does not have an explicit toolchain. A custom Runtime subclass, a third-party runtime type, or a Runtime from an incompatible BDN assembly version triggers the default branch.

Common situations: Subclassing Runtime to model a bespoke environment and expecting BDN to pick a toolchain. Mixing BDN versions where a runtime type from a newer assembly is passed to an older BDN. A null Runtime returned by a misconfigured EnvironmentResolver. A renamed/removed runtime type after a major BDN upgrade.

Related errors


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