OrchardCMS/OrchardCore · error · InvalidCastException
Cannot convert to UInt32
Error message
Cannot convert {value} to UInt32 What it means
This InvalidCastException is thrown by the explicit ushort conversion operator on JsonDynamicValue when the wrapped JSON value is null or cannot be read as a ushort. Note the message text says 'UInt32' even though the target type is UInt16 — a copy-paste inaccuracy in the library. The cast operator uses GetValue<ushort>() which fails when the underlying JSON element is not a numeric value in ushort range.
Solutions
- Check the wrapped value with GetObjectValue() (type and null) before casting
- Cast to ushort? instead — that operator returns null instead of throwing
- Validate the value is a whole number within 0-65535 first
- Use Convert.ToUInt16 on a string representation after a null check
Example fix
// before
var n = (ushort)dynamicValue;
// after
var obj = dynamicValue?.GetObjectValue();
if (obj is JsonElement el && el.ValueKind == JsonValueKind.Number && el.TryGetUInt16(out var n)) { /* use n */ } Defensive patterns
Strategy: type-guard
Validate before calling
if (value is null) throw new InvalidOperationException("Expected a numeric JSON value");
var obj = value.GetObjectValue();
if (obj is not JsonElement el || el.ValueKind != JsonValueKind.Number || !el.TryGetUInt16(out _))
throw new InvalidOperationException("JSON value is not a ushort-compatible number"); Type guard
static bool IsUshortLike(JsonDynamicValue? v) =>
v?.GetObjectValue() is JsonElement el && el.ValueKind == JsonValueKind.Number && el.TryGetUInt16(out _); Try / catch
ushort n;
try { n = (ushort)dynamicValue; }
catch (InvalidCastException ex) { /* log ex, use fallback */ n = 0; } Prevention
- Prefer the ushort? cast operator which returns null instead of throwing
- Inspect GetObjectValue() type before any explicit cast
- Validate numeric ranges (0-65535) when data comes from external APIs
- Never cast heterogeneous JSON arrays element-wise without kind checks
When it happens
Trigger: Casting a JsonDynamicValue with (ushort) when the wrapped JSON element is null, a string, an object/array, or a number outside 0-65535.
Common situations: Dynamic JSON data from an API where a field expected to be numeric arrives as a string or null; deserializing config-like JSON where an id/flag field is absent; iterating mixed-type JSON arrays and casting each element.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- Cannot convert to UInt64
- Cannot convert to Int16
- Cannot convert to Int32
- Cannot convert to Int64
- Cannot convert to SByte
AI-assisted analysis of OrchardCMS/OrchardCore@4306c0717f (2026-09-13).
Data as JSON: /api/errors/5610075841fe4405.
Report an issue: GitHub.
Appendix: source
Thrown at src/OrchardCore/OrchardCore.Abstractions/Json/Dynamic/JsonDynamicValue.cs:422
{
return value?._jsonValue?.GetValue<float>()
?? throw new InvalidCastException($"Cannot convert {value} to Float");
}
public static explicit operator float?(JsonDynamicValue value)
{
return value?._jsonValue?.GetValue<float?>();
}
public static explicit operator string?(JsonDynamicValue value)
{
return value?.ToString();
}
public static explicit operator ushort(JsonDynamicValue value)
{
return value?._jsonValue?.GetValue<ushort>()
?? throw new InvalidCastException($"Cannot convert {value} to UInt32");
}
public static explicit operator ushort?(JsonDynamicValue value)
{
return value?._jsonValue?.GetValue<ushort?>();
}
public static explicit operator uint(JsonDynamicValue value)
{
return value?._jsonValue?.GetValue<uint>()
?? throw new InvalidCastException($"Cannot convert {value} to UInt32");
}
public static explicit operator uint?(JsonDynamicValue value)
{
return value?._jsonValue?.GetValue<uint?>();
}
View on GitHub (pinned to 4306c0717f)