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

CompositeResolver.Resolve(CharacteristicObject, Characteristic) throws when the object does not already hold a value for the requested characteristic AND none of the resolvers in its chain can resolve it. CompositeResolver aggregates several IResolver instances (job/runtime/infrastructure resolvers) and resolves a characteristic by delegating to the first capable resolver; if the list is empty for that characteristic, there is no way to produce a default.

Source

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

    {
        private readonly IResolver[] resolvers;

        public CompositeResolver(params IResolver[] resolvers)
        {
            this.resolvers = resolvers;
        }

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

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

            var resolver = resolvers.FirstOrDefault(r => r.CanResolve(characteristic));
            if (resolver != null)
                return resolver.Resolve(obj, characteristic);
            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];

            var resolver = resolvers.FirstOrDefault(r => r.CanResolve(characteristic));
            if (resolver != null)
                return resolver.Resolve(obj, characteristic);
            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];

View on GitHub (pinned to b515068b61)

Solutions

  1. Ensure the resolver you pass to the CompositeResolver can resolve the characteristic (call CanResolve on it) before relying on Resolve.
  2. Set an explicit value on the characteristic (e.g. job.WithRuntime(...)) so the HasValue short-circuit applies instead of resolver lookup.
  3. Add the missing resolver (typically the framework/runtime/infrastructure default resolver) to the composite.
  4. If you do not need a value, call the Resolve(obj, characteristic, defaultValue) overload that returns a default instead of throwing.

Example fix

// before
var value = composite.Resolve(job, SomeCharacteristic);

// after
if (composite.CanResolve(SomeCharacteristic))
    var value = composite.Resolve(job, SomeCharacteristic);
else
    job = job.With(SomeCharacteristic, fallbackValue);
Defensive patterns

Strategy: validation

Validate before calling

if (!composite.CanResolve(characteristic))
    throw new InvalidOperationException($"Caller must set '{characteristic.Id}' before resolve.");
var value = composite.Resolve(obj, characteristic);

Type guard

bool CanResolveSafely(CompositeResolver r, Characteristic c) => r.CanResolve(c);

Try / catch

try { return composite.Resolve(obj, characteristic); }
catch (InvalidOperationException ex) when (ex.Message.Contains("no default resolver"))
{
    // set a sensible default or rethrow with context about the missing characteristic
}

Prevention

When it happens

Trigger: Calling obj.ResolveValue / Job.ResolveValue for a characteristic that was never set and for which no resolver (e.g. InfrastructureResolver, RuntimeResolver, JobResolver) was registered in the composite. Building a custom CompositeResolver whose resolver list omits the resolver that owns a given characteristic.

Common situations: Creating a hand-rolled resolver chain for tests or a custom hosting scenario, referencing a characteristic that only exists in a newer/older BDN version than the resolvers you wired up, or mutating a Job's resolver set after construction.

Related errors


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