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

  1. Cast to ulong? instead — that operator returns null instead of throwing
  2. Check GetObjectValue() for null and numeric kind before casting
  3. Parse with ulong.TryParse on the string representation when ids are strings
  4. 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

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


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)