OrchardCMS/OrchardCore · error · InvalidCastException
Cannot convert to Double
Error message
Cannot convert {value} to Double What it means
The explicit operator double on JsonDynamicValue converts via GetValue<double>() and throws InvalidCastException when the wrapped value is null or the JSON token cannot be represented as a double. The nullable operator (double?) exists for non-throwing access.
Solutions
- Ensure the JSON token is a JSON number before casting
- Use the nullable cast (double?) and handle null
- Pre-validate with double.TryParse on value.ToString() when the token may be a numeric string
- Null-check the JsonDynamicValue wrapper before casting
Example fix
// before var ratio = (double)jsonDynamicValue["Ratio"]; // after var ratio = (double?)jsonDynamicValue["Ratio"] ?? 0d;
Defensive patterns
Strategy: type-guard
Validate before calling
if (jsonDynamicValue is null) throw new InvalidOperationException("null wrapper");
var raw = jsonDynamicValue.ToString();
if (!double.TryParse(raw, NumberStyles.Float, CultureInfo.InvariantCulture, out _))
throw new InvalidOperationException($"'{raw}' is not a double");
var d = (double)jsonDynamicValue; Type guard
static bool TryGetDouble(JsonDynamicValue v, out double value)
{
value = default;
if (v is null) return false;
var d = (double?)v;
if (d is null) return false;
value = d.Value;
return true;
} Try / catch
double ratio;
try
{
ratio = (double)jsonDynamicValue["Ratio"];
}
catch (InvalidCastException ex)
{
ratio = 0d;
} Prevention
- Prefer (double?) casts for optional numeric fields
- Keep numeric values as JSON numbers in stored data
- Parse numeric strings with InvariantCulture before casting
- Cover wrong-type JSON cases in tests
When it happens
Trigger: Executing `(double)jsonDynamicValue` where the wrapper/_jsonValue is null or the token is a non-numeric string, boolean, object, or array.
Common situations: Numeric measurements in JSON stored as strings or null; dynamic access to content-item or configuration JSON where a field's type drifted; parsing third-party API payloads dynamically.
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 DateTime
- Cannot convert to DateTimeOffset
- Cannot convert to Decimal
- Cannot convert to Guid
- Cannot convert to
AI-assisted analysis of OrchardCMS/OrchardCore@4306c0717f (2026-09-13).
Data as JSON: /api/errors/7b49c9ec705ba399.
Report an issue: GitHub.
Appendix: source
Thrown at src/OrchardCore/OrchardCore.Abstractions/Json/Dynamic/JsonDynamicValue.cs:340
{
return value?._jsonValue?.GetValue<DateTimeOffset?>();
}
public static explicit operator decimal(JsonDynamicValue value)
{
return value?._jsonValue?.GetValue<decimal>()
?? throw new InvalidCastException($"Cannot convert {value} to Decimal");
}
public static explicit operator decimal?(JsonDynamicValue value)
{
return value?._jsonValue?.GetValue<decimal?>();
}
public static explicit operator double(JsonDynamicValue value)
{
return value?._jsonValue?.GetValue<double>()
?? throw new InvalidCastException($"Cannot convert {value} to Double");
}
public static explicit operator double?(JsonDynamicValue value)
{
return value?._jsonValue?.GetValue<double?>();
}
public static explicit operator Guid(JsonDynamicValue value)
{
return value?._jsonValue?.GetValue<Guid>()
?? throw new InvalidCastException($"Cannot convert {value} to Guid");
}
public static explicit operator Guid?(JsonDynamicValue value)
{
return value?._jsonValue?.GetValue<Guid?>();
}
View on GitHub (pinned to 4306c0717f)