dotnet/BenchmarkDotNet · error · ArgumentException

The value {value} is not assignable to {characteristic} prop

Error message

The value {value} is not assignable to {characteristic} property.

What it means

AssertIsAssignable validates that a value being stored on a characteristic is an instance of the characteristic's declared type (characteristicType). If it is not, ArgumentException is thrown with the characteristic Id as the param name. A separate branch throws ArgumentNullException when a null/EmptyValue is assigned to a characteristic that has child characteristics.

Source

Thrown at src/BenchmarkDotNet/Characteristics/CharacteristicObject.cs:91

        private void AssertIsNonFrozenRoot()
        {
            AssertNotFrozen();
            AssertIsRoot();
        }

        private static void AssertIsAssignable(Characteristic characteristic, object? value)
        {
            if (ReferenceEquals(value, Characteristic.EmptyValue) || ReferenceEquals(value, null))
            {
                if (characteristic.HasChildCharacteristics)
                    throw new ArgumentNullException(characteristic.Id);

                return;
            }

            if (!characteristic.CharacteristicType.GetTypeInfo().IsInstanceOfType(value))
                throw new ArgumentException(
                    $"The value {value} is not assignable to {characteristic} property.",
                    characteristic.Id);
        }
        #endregion

        #region Properties

        private CharacteristicObject? Owner { get; set; }

        protected CharacteristicObject OwnerOrSelf => Owner ?? this;

        public bool Frozen => Owner?.Frozen ?? frozen;

        protected virtual bool IsPropertyBag => false;

        public bool HasChanges => GetCharacteristicsWithValues().Any(c => c.IsPresentableCharacteristic());
        #endregion

View on GitHub (pinned to b515068b61)

Solutions

  1. Check characteristic.CharacteristicType.IsInstanceOfType(value) before assigning, exactly as the assertion does.
  2. Convert/coerce the value to the characteristic's declared type before setting it.
  3. For composite characteristics, never assign null; set sub-values individually instead.
  4. Validate types at the boundary where external data enters the characteristic system.

Example fix

// before
characteristic[job] = value; // value is wrong type

// after
if (!characteristic.CharacteristicType.IsInstanceOfType(value))
    value = Convert.ChangeType(value, characteristic.CharacteristicType);
characteristic[job] = value;
Defensive patterns

Strategy: validation

Validate before calling

if (!characteristic.CharacteristicType.IsInstanceOfType(value))
    value = Convert.ChangeType(value, characteristic.CharacteristicType);
characteristic[obj] = value;

Type guard

static bool IsAssignable(Characteristic c, object? v)
    => v is null ? !c.HasChildCharacteristics : c.CharacteristicType.IsInstanceOfType(v);

Try / catch

try { characteristic[obj] = value; }
catch (ArgumentException ex) when (ex.Message.Contains("not assignable"))
{
    // coerce value to characteristic.CharacteristicType and retry, or reject input
}

Prevention

When it happens

Trigger: Assigning a value whose runtime type does not match the characteristic's declared type (e.g. a string into an int characteristic), assigning null to a composite/child-bearing characteristic, or a mis-typed generic characteristic constructed via reflection.

Common situations: Programmatically building characteristics with mismatched generics, deserializing config values into the wrong CLR type, or copy/merge logic that moves values between characteristics of different declared types.

Related errors


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