JamesNK/Newtonsoft.Json · error · NotSupportedException

Newtonsoft.Json serialization is not compatible with trimmin

Error message

Newtonsoft.Json serialization is not compatible with trimming and has been disabled. Newtonsoft.Json.Linq.JToken.SerializationIsSupported is set to false.

What it means

Thrown from JValue's IConvertible.ToType implementation when Convert.ChangeType (or any IConvertible consumer) routes to JValue.ToType on a trimmed/AOT build where the feature switch Newtonsoft.Json.Linq.JToken.SerializationIsSupported is false. ToType internally calls ToObject(conversionType), which requires reflection-based serialization that trimming removes; the guard rejects it with NotSupportedException instead of producing a trim-induced failure at runtime.

Source

Thrown at Src/Newtonsoft.Json/Linq/JValue.cs:1206

            return (double)this;
        }

        decimal IConvertible.ToDecimal(IFormatProvider? provider)
        {
            return (decimal)this;
        }

        DateTime IConvertible.ToDateTime(IFormatProvider? provider)
        {
            return (DateTime)this;
        }

        object IConvertible.ToType(Type conversionType, IFormatProvider? provider)
        {
#if HAVE_APPCONTEXT
            if (!SerializationIsSupported)
            {
                throw new NotSupportedException(SerializationNotSupportedMessage);
            }
#endif
#pragma warning disable IL2026, IL3050
            return ToObject(conversionType)!;
#pragma warning restore IL2026, IL3050
        }
#endif
    }
}

View on GitHub (pinned to 4f73e74372)

Solutions

  1. Use the AOT-safe explicit API: jvalue.ToObject<T>() annotated appropriately, or cast via the explicit operators ((int)jvalue).
  2. Deserialize via JsonSerializer with source-generated context instead of IConvertible routing.
  3. If IConvertible routing is mandatory on a non-trimmed build, set Newtonsoft.Json.Linq.JToken.SerializationIsSupported=true and disable trimming.

Example fix

// before
var dt = (DateTime)Convert.ChangeType(jvalue, typeof(DateTime));

// after
var dt = (DateTime)jvalue;
// or
var dt = jvalue.ToObject<DateTime>();
Defensive patterns

Strategy: validation

Validate before calling

var v = (DateTime)jvalue; // use explicit cast instead of Convert.ChangeType

Type guard

static bool IsSerializationSupported => AppContext.TryGetSwitch("Newtonsoft.Json.Linq.JToken.SerializationIsSupported", out bool s) ? s : true;

Try / catch

try { var v = Convert.ChangeType(jvalue, typeof(T)); } catch (NotSupportedException) { /* fall back to explicit cast */ }

Prevention

When it happens

Trigger: Calling Convert.ChangeType(jvalue, typeof(SomeType)) or any code path that invokes the IConvertible.ToType route on a JValue, in a trimmed/AOT-published app or with Newtonsoft.Json.Linq.JToken.SerializationIsSupported=false. Less commonly, direct casts routed through IConvertible.

Common situations: Native AOT / trimmed self-contained deployments; MAUI/Blazor WASM; manually setting the switch off after seeing IL2026 warnings; generic conversion helpers that go through Convert.ChangeType.

Related errors


AI-assisted analysis of JamesNK/Newtonsoft.Json@4f73e74372 (2026-08-07). Data as JSON: /api/errors/a2341b8637404594. Report an issue: GitHub.