dotnet/BenchmarkDotNet · info · InvalidOperationException

Please use Targets property

Error message

Please use Targets property

What it means

TargetedAttribute is the base class for targeting attributes such as [Benchmark]. The library migrated the single-method 'Target' string property to a 'Targets' string[] array. The 'Target' getter is preserved only because C# attribute syntax requires a read-write property pair; calling the getter throws to redirect consumers to the 'Targets' array. The setter still works (it splits on ',' and stores into Targets) for backward compatibility.

Solutions

  1. Read the 'Targets' string[] property instead of 'Target': attribute.Targets.Contains(methodName).
  2. When writing new attributes, set [Benchmark(Target = "Foo")] is fine for input; just never call the getter.
  3. If reflecting, filter for the 'Targets' property name and skip 'Target'.

Example fix

// before
var name = ((TargetedAttribute)attr).Target; // throws

// after
var names = ((TargetedAttribute)attr).Targets;
var match = names.Length == 0 || names.Contains("MyMethod");
Defensive patterns

Strategy: validation

Validate before calling

// Before reading, branch on Targets and never touch the Target getter:
static bool IsTargeted(TargetedAttribute attr, string methodName)
    => attr.Targets.Length == 0 || attr.Targets.Contains(methodName);

Prevention

When it happens

Trigger: Programmatically reading the 'Target' property via reflection at runtime (e.g. typeof(X).GetCustomAttributes().Target, or iterating attribute properties). Happens in custom tooling that inspects [Benchmark] / [ParamsSource]-style targeted attributes, or in code ported from an older BDN version that read '.Target'.

Common situations: Upgrading BenchmarkDotNet past the Target->Targets rename while keeping code that accesses the old single-value property; building analyzers/utilities that reflect over benchmark attributes.

Related errors


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

Appendix: source

Thrown at src/BenchmarkDotNet.Annotations/Attributes/TargetedAttribute.cs:17

using System.Reflection;

namespace BenchmarkDotNet.Attributes
{
    /// <summary>
    /// Base class for attributes that are targeted at one or more method(s)
    /// </summary>
    public abstract class TargetedAttribute : Attribute
    {
        public string[] Targets { get; set; } = [];

        /// <summary>
        /// Target method for attribute
        /// </summary>
        public string Target
        {
            get => throw new InvalidOperationException("Please use Targets property"); // kept to keep compiler happy "Named attribute arguments must be fields which are not readonly, static, or const, or read-write properties which are public and not static."
            set => Targets = string.IsNullOrEmpty(value) ? [] : value.Split(','); // , is for backward compat
        }

        public bool Match(MethodInfo method) => Targets.Length == 0 || Targets.Contains(method.Name);
    }
}

View on GitHub (pinned to b515068b61)