dotnet/BenchmarkDotNet · error · InvalidOperationException

There is no default resolver for {characteristic.FullId}

Error message

There is no default resolver for {characteristic.FullId}

What it means

The single Resolver class (base for resolvers like InfrastructureResolver) keeps a dictionary of characteristic->resolver-func registrations. The non-generic Resolve throws InvalidOperationException when resolvers.TryGetValue finds no entry for the requested characteristic, i.e. that specific Resolver instance never had Register(...) called for it.

Source

Thrown at src/BenchmarkDotNet/Characteristics/Resolver.cs:24

    {
        private readonly Dictionary<Characteristic, Func<CharacteristicObject, object?>> resolvers = [];

        protected void Register<[DynamicallyAccessedMembers(CharacteristicObject.CharacteristicMemberTypes)] T>(Characteristic<T> characteristic, Func<T?> resolver) =>
            resolvers[characteristic] = obj => resolver();

        protected void Register<[DynamicallyAccessedMembers(CharacteristicObject.CharacteristicMemberTypes)] T>(Characteristic<T> characteristic, Func<CharacteristicObject, T?> resolver) =>
            resolvers[characteristic] = obj => resolver(obj);

        public bool CanResolve(Characteristic characteristic) => resolvers.ContainsKey(characteristic);

        public object? Resolve(CharacteristicObject obj, Characteristic characteristic)
        {
            if (obj.HasValue(characteristic))
                return characteristic[obj];

            if (resolvers.TryGetValue(characteristic, out var resolver))
                return resolver(obj);
            throw new InvalidOperationException($"There is no default resolver for {characteristic.FullId}");
        }

        public T? Resolve<[DynamicallyAccessedMembers(CharacteristicObject.CharacteristicMemberTypes)] T>(CharacteristicObject obj, Characteristic<T> characteristic)
        {
            if (obj.HasValue(characteristic))
                return characteristic[obj];

            if (resolvers.TryGetValue(characteristic, out var resolver))
                return (T?)resolver(obj);
            throw new InvalidOperationException($"There is no default resolver for {characteristic.FullId}");
        }

        public object? Resolve(CharacteristicObject obj, Characteristic characteristic, object defaultValue)
        {
            if (obj.HasValue(characteristic))
                return characteristic[obj];

            if (resolvers.TryGetValue(characteristic, out var resolver))

View on GitHub (pinned to b515068b61)

Solutions

  1. Register the characteristic in the resolver: resolver.Register(characteristic, obj => ...) inside its constructor.
  2. Route the request through the CompositeResolver / correct specialized resolver that owns the characteristic.
  3. Check resolver.CanResolve(characteristic) (which is resolvers.ContainsKey) before calling Resolve.
  4. Set an explicit value on the object so the HasValue path is taken instead.

Example fix

// before
var v = resolver.Resolve(obj, characteristic); // not registered

// after
if (resolver.CanResolve(characteristic))
    var v = resolver.Resolve(obj, characteristic);
else
    obj = obj.With(characteristic, fallback);
Defensive patterns

Strategy: validation

Validate before calling

if (!resolver.CanResolve(characteristic))
    throw new InvalidOperationException($"Resolver '{resolver.GetType().Name}' cannot resolve '{characteristic.Id}'.");
return resolver.Resolve(obj, characteristic);

Type guard

bool ResolverOwns(Resolver r, Characteristic c) => r.CanResolve(c);

Try / catch

try { return resolver.Resolve(obj, characteristic); }
catch (InvalidOperationException ex) when (ex.Message.Contains("no default resolver"))
{
    // route to the resolver that owns the characteristic, or register it
}

Prevention

When it happens

Trigger: Calling Resolve on a Resolver for a characteristic it was not built to handle (asking the InfrastructureResolver for a runtime characteristic, for instance), or a custom Resolver subclass that forgot to register one of its characteristics.

Common situations: Subclassing Resolver and omitting a Register call, querying a characteristic against the wrong resolver instance, or a version mismatch where a characteristic exists but its resolver registration was removed.

Related errors


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