OrchardCMS/OrchardCore · error · InvalidCastException

Cannot convert to Byte array

Error message

Cannot convert {value} to Byte array

What it means

This InvalidCastException is thrown by the explicit byte[] conversion operator on JsonDynamicValue when the wrapped JSON value is not a string, because base64 decoding requires the underlying GetObjectValue() to yield a string. JSON has no native byte[] type, so the library only accepts a base64-encoded string.

Solutions

  1. Ensure the JSON field is a base64-encoded string before casting
  2. Get the value as string first and use Convert.FromBase64String inside your own try/catch or TryFromBase64String
  3. Validate with GetObjectValue() is string before the cast
  4. Fix the producer to serialize binary as base64 string

Example fix

// before
var bytes = (byte[])dynamicValue;
// after
if (dynamicValue?.GetObjectValue() is string s && Convert.TryFromBase64String(s, new byte[s.Length * 3 / 4], out _))
{
    var bytes = Convert.FromBase64String(s);
}
Defensive patterns

Strategy: type-guard

Validate before calling

if (value?.GetObjectValue() is not string b64 || !Convert.TryFromBase64String(b64, new byte[b64.Length * 3 / 4], out _))
    throw new InvalidOperationException("JSON value is not a base64 string");

Type guard

static bool IsBase64String(JsonDynamicValue? v) =>
    v?.GetObjectValue() is string s && s.Length % 4 == 0 && Convert.TryFromBase64String(s, new byte[s.Length * 3 / 4], out _);

Try / catch

byte[] bytes;
try { bytes = (byte[])dynamicValue; }
catch (InvalidCastException ex) { /* log, fallback */ bytes = Array.Empty<byte>(); }

Prevention

When it happens

Trigger: Casting a JsonDynamicValue with (byte[]) when the wrapped value is a number, boolean, object, array, or null rather than a base64 string.

Common situations: Binary data fields that a producer serialized as a plain array of numbers instead of a base64 string; null fields; non-base64 strings will also fail inside Convert.FromBase64String.

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/6e7daca42e701814. Report an issue: GitHub.

Appendix: source

Thrown at src/OrchardCore/OrchardCore.Abstractions/Json/Dynamic/JsonDynamicValue.cs:459

    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)
    {
        if (value?._jsonValue?.GetObjectValue() is string str)
        {
            return TimeSpan.Parse(str, CultureInfo.InvariantCulture);
        }

        throw new InvalidCastException($"Cannot convert {value} to TimeSpan");
    }

    public static explicit operator TimeSpan?(JsonDynamicValue value)
    {
        var str = value?._jsonValue?.GetObjectValue() as string;

        return str is not null
            ? TimeSpan.Parse(str, CultureInfo.InvariantCulture)

View on GitHub (pinned to 4306c0717f)