OrchardCMS/OrchardCore · error · InvalidCastException
Cannot convert to Int32
Error message
Cannot convert {value} to Int32 What it means
JsonDynamicValue wraps a JSON value and exposes explicit conversion operators for primitive types. The explicit operator int casts _jsonValue.GetValue<int>(); if the underlying JSON value is absent, null, or not representable as an Int32, the operator returns null and throws InvalidCastException with 'Cannot convert {value} to Int32'. It signals that the requested numeric conversion is not possible for the wrapped JSON token.
Solutions
- Cast to int? (explicit operator int?) instead of int, 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 within Int32 range before casting.
- Ensure the JSON field is stored as a JSON number; fix the producer or deserialize the string via int.Parse when it is intentionally a string.
- Wrap the cast in try/catch for InvalidCastException if the value is genuinely optional.
Example fix
// before
int count = (int)jsonValue; // throws when jsonValue is "123" (string)
// after
int? count = (int?)jsonValue;
if (count is null) { /* handle missing/invalid value */ } Defensive patterns
Strategy: type-guard
Validate before calling
if (jsonValue is null || jsonValue.Type != JTokenType.Integer)
throw new InvalidOperationException("Expected an integer JSON value for Int32 cast."); Type guard
static bool IsConvertibleToInt32(JsonDynamicValue v) =>
v?._jsonValue is { Type: JTokenType.Integer } t && t.Value<long>() is >= int.MinValue and <= int.MaxValue; Try / catch
try
{
int n = (int)jsonValue;
}
catch (InvalidCastException ex)
{
// log and fall back to a default or skip the record
int n = default;
} Prevention
- Prefer the nullable cast (int?) which returns null instead of throwing.
- Confirm the JSON token is JTokenType.Integer before casting.
- Watch for upstream schema changes that turn numeric fields into strings.
When it happens
Trigger: Casting a JsonDynamicValue instance to int with (int)jsonDynamicValue when the wrapped JSON token is null, not a number (e.g. a JSON string or object), or a number outside the Int32 range, causing GetValue<int>() to yield null.
Common situations: Reading a JSON id or count field that is a string ("123"), casting a fractional or very large number that Json.NET's GetValue<int> rejects, casting on a JsonDynamicValue built from a null token, or upstream data changing from number to string.
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 Int64
- 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/ca5dce6106af89f3.
Report an issue: GitHub.
Appendix: source
Thrown at src/OrchardCore/OrchardCore.Abstractions/Json/Dynamic/JsonDynamicValue.cs:373
{
return value?._jsonValue?.GetValue<Guid?>();
}
public static explicit operator short(JsonDynamicValue value)
{
return value?._jsonValue?.GetValue<short>()
?? throw new InvalidCastException($"Cannot convert {value} to Int16");
}
public static explicit operator short?(JsonDynamicValue value)
{
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?>();
}
View on GitHub (pinned to 4306c0717f)