OrchardCMS/OrchardCore · error · InvalidCastException
Cannot convert to Guid
Error message
Cannot convert {value} to Guid What it means
The explicit operator Guid on JsonDynamicValue converts via GetValue<Guid>() and throws InvalidCastException when the result is null or the JSON token is not a parseable GUID string. It fails fast with a descriptive message; use the (Guid?) operator for non-throwing access.
Solutions
- Confirm the JSON value is a valid GUID string (32 hex digits / with-dashes format) before casting
- Use the nullable cast (Guid?) and treat null as 'no identifier'
- Validate with Guid.TryParse(value.ToString(), out var g) first, especially if IDs may be non-GUID strings
- Null-check the wrapper before casting
Example fix
// before var id = (Guid)jsonDynamicValue["ContentItemId"]; // after var id = (Guid?)jsonDynamicValue["ContentItemId"] ?? Guid.NewGuid();
Defensive patterns
Strategy: type-guard
Validate before calling
if (jsonDynamicValue is null) throw new InvalidOperationException("null wrapper");
var raw = jsonDynamicValue.ToString();
if (!Guid.TryParse(raw, out _))
throw new InvalidOperationException($"'{raw}' is not a GUID");
var g = (Guid)jsonDynamicValue; Type guard
static bool TryGetGuid(JsonDynamicValue v, out Guid value)
{
value = default;
if (v is null) return false;
var g = (Guid?)v;
if (g is null) return false;
value = g.Value;
return true;
} Try / catch
Guid id;
try
{
id = (Guid)jsonDynamicValue["ContentItemId"];
}
catch (InvalidCastException ex)
{
id = Guid.Empty;
} Prevention
- Use (Guid?) when an identifier may be missing
- Validate identifier format at the boundary before dynamic casting
- Do not repurpose GUID fields to hold non-GUID values (slugs, ints)
- Assert expected JSON schema in integration tests
When it happens
Trigger: Executing `(Guid)jsonDynamicValue` where the wrapper/_jsonValue is null or the token is a string not in a GUID-parseable format, a number, boolean, object, or array.
Common situations: Identifier fields (content item IDs, relation keys) in JSON that are null, empty, or stored in a non-GUID format (e.g. integers or short slugs); data migrated from another system that used different ID formats.
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 Double
- Cannot convert to
AI-assisted analysis of OrchardCMS/OrchardCore@4306c0717f (2026-09-13).
Data as JSON: /api/errors/187ca3e6728e2295.
Report an issue: GitHub.
Appendix: source
Thrown at src/OrchardCore/OrchardCore.Abstractions/Json/Dynamic/JsonDynamicValue.cs:351
{
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?>();
}
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?>();
}
View on GitHub (pinned to 4306c0717f)