OrchardCMS/OrchardCore · error · InvalidCastException
Cannot convert to Int64
Error message
Cannot convert {value} to Int64 What it means
JsonDynamicValue wraps a JSON value and exposes explicit conversion operators for primitive types. The explicit operator long casts _jsonValue.GetValue<long>(); if the underlying JSON value is absent, null, or not representable as an Int64, the operator returns null and throws InvalidCastException with 'Cannot convert {value} to Int64'. It signals that the requested numeric conversion is not possible for the wrapped JSON token.
Solutions
- Cast to long? (explicit operator long?) instead of long, which returns null instead of throwing, then handle the null case.
- Validate the JSON value with TryGetValue/GetValue and confirm it is an integral number before casting.
- Ensure the JSON field is a JSON number; if it is a string, parse it explicitly (long.TryParse) instead of casting.
- Wrap the cast in try/catch for InvalidCastException if the value is genuinely optional.
Example fix
// before
long id = (long)jsonValue; // throws when jsonValue is 3.14 or "9007199254740993"
// after
long? id = (long?)jsonValue;
if (id is null) { /* handle missing/invalid value */ } Defensive patterns
Strategy: type-guard
Validate before calling
if (jsonValue is null || (jsonValue.Type != JTokenType.Integer && jsonValue.Type != JTokenType.Float))
throw new InvalidOperationException("Expected a numeric JSON value for Int64 cast."); Type guard
static bool IsConvertibleToInt64(JsonDynamicValue v) =>
v?._jsonValue is { Type: JTokenType.Integer }; Try / catch
try
{
long n = (long)jsonValue;
}
catch (InvalidCastException ex)
{
// log and fall back to a default or skip the record
long n = default;
} Prevention
- Use the nullable cast (long?) so missing/non-numeric values yield null instead of throwing.
- Reject fractional or string-encoded numbers at the deserialization boundary.
- Check the JToken type with TryGetValue before casting large ids or timestamps.
When it happens
Trigger: Casting a JsonDynamicValue instance to long with (long)jsonDynamicValue when the wrapped JSON token is null, not a number, or a non-integral/overflowing number (e.g. 3.14 or a value beyond Int64), causing GetValue<long>() to yield null.
Common situations: Reading timestamps or large ids stored as fractional numbers or numeric strings, casting on a JsonDynamicValue constructed from a null/default _jsonValue, or JSON produced by another language serializing longs as strings.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Cannot convert to Int16
- Cannot convert to Int32
- Cannot convert to SByte
- Cannot convert to Float
- Cannot convert to UInt32
AI-assisted analysis of OrchardCMS/OrchardCore@4306c0717f (2026-09-13).
Data as JSON: /api/errors/b4d7db4cf6c268c9.
Report an issue: GitHub.
Appendix: source
Thrown at src/OrchardCore/OrchardCore.Abstractions/Json/Dynamic/JsonDynamicValue.cs:384
{
return value?._jsonValue?.GetValue<short?>();
}
public static explicit operator int(JsonDynamicValue value)
{
return value?._jsonValue?.GetValue<int>()
?? throw new InvalidCastException($"Cannot convert {value} to Int32");
}
public static explicit operator int?(JsonDynamicValue value)
{
return value?._jsonValue?.GetValue<int?>();
}
public static explicit operator long(JsonDynamicValue value)
{
return value?._jsonValue?.GetValue<long>()
?? throw new InvalidCastException($"Cannot convert {value} to Int64");
}
public static explicit operator long?(JsonDynamicValue value)
{
return value?._jsonValue?.GetValue<long?>();
}
public static explicit operator sbyte(JsonDynamicValue value)
{
return value?._jsonValue?.GetValue<sbyte>()
?? throw new InvalidCastException($"Cannot convert {value} to SByte");
}
public static explicit operator sbyte?(JsonDynamicValue value)
{
return value?._jsonValue?.GetValue<sbyte?>();
}
View on GitHub (pinned to 4306c0717f)