JamesNK/Newtonsoft.Json · error · NotSupportedException
Newtonsoft.Json support for dynamic is not compatible with…
Error message
Newtonsoft.Json support for dynamic is not compatible with trimming and has been disabled. Newtonsoft.Json.Linq.JToken.DynamicIsSupported is set to false.
What it means
Same dynamic-trimming guard as the JToken version, raised from JValue.GetMetaObject (the overridden IDynamicMetaObjectProvider hook). When the runtime attempts dynamic dispatch (dynamic keyword / ConvertBinder) against a JValue and the feature switch Newtonsoft.Json.Linq.JToken.DynamicIsSupported is false, Newtonsoft throws NotSupportedException. JValue has its own JValueDynamicProxy that relies on reflection/MakeDynamic, which trimming removes, so the guard protects AOT/trimmed apps.
Solutions
- Use explicit casts/indexers instead of dynamic: (int)jvalue or jvalue.Value<int>().
- Deserialize to a strongly typed POCO with ToObject<T>().
- If dynamic is required on a full-framework/non-trimmed build, set Newtonsoft.Json.Linq.JToken.DynamicIsSupported=true and disable trimming.
Example fix
// before dynamic dyn = jvalue; int n = dyn; // after int n = jvalue.Value<int>();
Defensive patterns
Strategy: validation
Validate before calling
// Avoid dynamic on JValue in trimmed builds; cast explicitly var n = jvalue.Value<int>();
Type guard
static bool IsDynamicSupported => AppContext.TryGetSwitch("Newtonsoft.Json.Linq.JToken.DynamicIsSupported", out bool s) ? s : true; Try / catch
try { dynamic d = jvalue; var x = (int)d; } catch (NotSupportedException) { /* use explicit cast */ } Prevention
- Do not use the dynamic keyword against JValue in trimmed/AOT apps.
- Prefer explicit operators and Value<T>().
- Confirm PublishTrimmed/PublishAot implications before adopting dynamic.
When it happens
Trigger: dynamic dyn = jvalue; var x = dyn.SomeProperty; on a trimmed/AOT-published app, or with the AppContext switch Newtonsoft.Json.Linq.JToken.DynamicIsSupported=false. The JValue-specific proxy (TryConvert/TryGetMember) is what triggers GetMetaObject.
Common situations: Publishing with PublishTrimmed/PublishAot; Blazor WASM/MAUI trimmed apps; flipping the switch off after trim warnings; dynamic conversions of JValue to other types.
Related errors
- Newtonsoft.Json support for dynamic is not compatible with…
- Newtonsoft.Json serialization is not compatible with…
- Newtonsoft.Json serialization is not compatible with…
- Newtonsoft.Json support for dynamic is not compatible with…
- Cannot access child value on
AI-assisted analysis of JamesNK/Newtonsoft.Json@4f73e74372 (2026-08-07).
Data as JSON: /api/errors/7467ed913568248a.
Report an issue: GitHub.
Appendix: source
Thrown at Src/Newtonsoft.Json/Linq/JValue.cs:980
{
return _value.ToString()!;
}
}
#if HAVE_DYNAMIC
/// <summary>
/// Returns the <see cref="DynamicMetaObject"/> responsible for binding operations performed on this object.
/// </summary>
/// <param name="parameter">The expression tree representation of the runtime value.</param>
/// <returns>
/// The <see cref="DynamicMetaObject"/> to bind this object.
/// </returns>
protected override DynamicMetaObject GetMetaObject(Expression parameter)
{
#if HAVE_APPCONTEXT
if (!DynamicIsSupported)
{
throw new NotSupportedException(DynamicNotSupportedMessage);
}
#endif
#pragma warning disable IL2026, IL3050
return new DynamicProxyMetaObject<JValue>(parameter, this, new JValueDynamicProxy());
#pragma warning restore IL2026, IL3050
}
[RequiresUnreferencedCode(MiscellaneousUtils.TrimWarning)]
[RequiresDynamicCode(MiscellaneousUtils.AotWarning)]
private class JValueDynamicProxy : DynamicProxy<JValue>
{
public override bool TryConvert(JValue instance, ConvertBinder binder, [NotNullWhen(true)]out object? result)
{
if (binder.Type == typeof(JValue) || binder.Type == typeof(JToken))
{
result = instance;
return true;
}View on GitHub (pinned to 4f73e74372)