OrchardCMS/OrchardCore · error · InvalidCastException
Cannot convert to UInt64
Error message
Cannot convert {value} to UInt64 What it means
This InvalidCastException is thrown by the explicit ulong conversion operator on JsonDynamicValue when the wrapped JSON value is null or cannot be read as a ulong. GetValue<ulong>() effectively returns null when the underlying JsonElement is not a number, triggering the ?? throw. The message correctly names the target type UInt64.
Solutions
- Cast to ulong? instead — that operator returns null instead of throwing
- Check GetObjectValue() for null and numeric kind before casting
- Parse with ulong.TryParse on the string representation when ids are strings
- Validate the numeric range before the cast
Example fix
// before
var id = (ulong)dynamicValue;
// after
var id = (ulong?)dynamicValue ?? throw new InvalidOperationException("Expected numeric id"); Defensive patterns
Strategy: type-guard
Validate before calling
var obj = value?.GetObjectValue();
if (obj is JsonElement el && el.ValueKind == JsonValueKind.Number && el.TryGetUInt64(out _)) { /* safe */ }
else if (obj is string s && ulong.TryParse(s, out _)) { /* string-encoded id, parse manually */ } Type guard
static bool IsUlongLike(JsonDynamicValue? v) =>
v?.GetObjectValue() is JsonElement el && el.ValueKind == JsonValueKind.Number && el.TryGetUInt64(out _); Try / catch
ulong id;
try { id = (ulong)dynamicValue; }
catch (InvalidCastException ex) { /* log, fallback */ id = 0UL; } Prevention
- Prefer the ulong? cast operator which returns null instead of throwing
- Treat 64-bit ids serialized as strings separately (ulong.TryParse)
- Check for JSON null before casting fields from partial responses
- Check ValueKind == Number before casting
When it happens
Trigger: Casting a JsonDynamicValue with (ulong) when the wrapped JSON element is null, a string, an object/array, or a number outside ulong range (e.g. 64-bit ids serialized as strings).
Common situations: Snowflake/timestamp-style ids that arrive as JSON strings; null fields from partial API responses; casting heterogeneous JSON array elements.
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 UInt32
- 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/8f4bde72cbf82288.
Report an issue: GitHub.
Appendix: source
Thrown at src/OrchardCore/OrchardCore.Abstractions/Json/Dynamic/JsonDynamicValue.cs:444
{
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?>();
}
public static explicit operator ulong(JsonDynamicValue value)
{
return value?._jsonValue?.GetValue<ulong>()
?? throw new InvalidCastException($"Cannot convert {value} to UInt64");
}
public static explicit operator ulong?(JsonDynamicValue value)
{
return value?._jsonValue?.GetValue<ulong?>();
}
public static explicit operator byte[]?(JsonDynamicValue value)
{
if (value?._jsonValue.GetObjectValue() is string str)
{
return Convert.FromBase64String(str);
}
throw new InvalidCastException($"Cannot convert {value} to Byte array");
}
public static explicit operator TimeSpan(JsonDynamicValue value)View on GitHub (pinned to 4306c0717f)