OrchardCMS/OrchardCore · error · InvalidOperationException

Cannot convert to

Error message

Cannot convert {this} to {conversionType}

What it means

JsonDynamicValue implements IConvertible; when ToType is called the underlying JValue is converted with ToObject(conversionType). If the JSON value cannot be converted to the requested type (or the value is null), an InvalidOperationException with 'Cannot convert ...' is thrown.

Solutions

  1. Check the underlying JSON token type (JsonValue.Type) before converting and branch on it.
  2. Use ToString(provider) plus type-specific parsing (int.TryParse, DateTime.Parse with culture) for resilient conversion.
  3. Handle null dynamic values explicitly before invoking conversion.
  4. Catch InvalidOperationException and fall back to a default value appropriate for the field.

Example fix

// before
var count = (int)Convert.ChangeType(jsonValue, typeof(int));
// after
var raw = jsonValue?.ToString();
var count = int.TryParse(raw, NumberStyles.Any, CultureInfo.InvariantCulture, out var c) ? c : 0;
Defensive patterns

Strategy: type-guard

Validate before calling

// Confirm the underlying token supports the target conversion
bool CanConvertTo(JsonDynamicValue v, Type t) =>
    v?._jsonValue != null &&
    !(t.IsPrimitive && (v._jsonValue.Type == JTokenType.Object || v._jsonValue.Type == JTokenType.Array));

Type guard

static bool IsConvertible<T>(JsonDynamicValue v, out T result)
{
    try { result = (T)Convert.ChangeType(v?.ToString(), typeof(T), CultureInfo.InvariantCulture); return true; }
    catch { result = default; return false; }
}

Try / catch

try
{
    var converted = Convert.ChangeType(jsonValue, conversionType, CultureInfo.InvariantCulture);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("Cannot convert"))
{
    // fall back to string parsing or a default value
}

Prevention

When it happens

Trigger: Calling Convert.ChangeType(dynamicJsonValue, someType) or another IConvertible.ToType path where the JValue's runtime JSON type is incompatible with conversionType — e.g. converting a JSON string "abc" to int, an object/array to a primitive, or a null value to any type.

Common situations: Dynamic content-field values whose shape changed between data versions; recipes importing strings that were assumed numeric; querying dynamic documents and casting values with Convert.ChangeType.

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


AI-assisted analysis of OrchardCMS/OrchardCore@4306c0717f (2026-09-13). Data as JSON: /api/errors/4f2a11b94efc7cf1. Report an issue: GitHub.

Appendix: source

Thrown at src/OrchardCore/OrchardCore.Abstractions/Json/Dynamic/JsonDynamicValue.cs:233

    sbyte IConvertible.ToSByte(IFormatProvider? provider)
    {
        return (sbyte)this;
    }

    float IConvertible.ToSingle(IFormatProvider? provider)
    {
        return (float)this;
    }

    string IConvertible.ToString(IFormatProvider? provider)
    {
        return ToString(provider);
    }

    object IConvertible.ToType(Type conversionType, IFormatProvider? provider)
    {
        return _jsonValue?.ToObject(conversionType)
            ?? throw new InvalidOperationException($"Cannot convert {this} to {conversionType}");
    }

    ushort IConvertible.ToUInt16(IFormatProvider? provider)
    {
        return (ushort)this;
    }

    uint IConvertible.ToUInt32(IFormatProvider? provider)
    {
        return (uint)this;
    }

    ulong IConvertible.ToUInt64(IFormatProvider? provider)
    {
        return (ulong)this;
    }

    public static bool operator ==(JsonDynamicValue left, JsonDynamicValue right)

View on GitHub (pinned to 4306c0717f)