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
- Check characteristic.CharacteristicType.IsInstanceOfType(value) before assigning, exactly as the assertion does.
- Convert/coerce the value to the characteristic's declared type before setting it.
- For composite characteristics, never assign null; set sub-values individually instead.
- 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
- Validate the value type at the boundary where external data enters the characteristic system.
- Never assign null to a composite (child-bearing) characteristic; set sub-values individually.
- Keep generic characteristic types consistent with the values you feed them.
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
- String cannot be empty.
- String cannot be empty or whitespace.
- Property name must be non-empty.
- Value cannot be null. (Parameter 'values')
- 'source' cannot be null or whitespace.
AI-assisted analysis of dotnet/BenchmarkDotNet@b515068b61 (2026-08-13).
Data as JSON: /api/errors/9709821024a8148b.
Report an issue: GitHub.