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
- Ensure the JSON field is a base64-encoded string before casting
- Get the value as string first and use Convert.FromBase64String inside your own try/catch or TryFromBase64String
- Validate with GetObjectValue() is string before the cast
- 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
- Ensure producers serialize binary data as base64 strings, not numeric arrays
- Reject or convert numeric-array binary fields before casting
- Validate base64 format (length, charset) before casting
- Handle JSON null explicitly
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
- Cannot convert to Int16
- Cannot convert to Int32
- Cannot convert to Int64
- Cannot convert to SByte
- Cannot convert to Float
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)