JamesNK/Newtonsoft.Json · error · NotSupportedException
Newtonsoft.Json support for dynamic is not compatible with t
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
Thrown by JObject.GetMetaObject (the IDynamicMetaObjectProvider surface) when dynamic-language binding is used against a JObject and the AppContext switch 'Newtonsoft.Json.Linq.JToken.DynamicIsSupported' is false. Dynamic dispatch on JObject relies on reflection/emission that trimming and Native AOT cannot support, so it is gated behind the switch.
Source
Thrown at Src/Newtonsoft.Json/Linq/JObject.cs:847
}
#endregion
#endif
#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<JObject>(parameter, this, new JObjectDynamicProxy());
#pragma warning restore IL2026, IL3050
}
private class JObjectDynamicProxy : DynamicProxy<JObject>
{
public override bool TryGetMember(JObject instance, GetMemberBinder binder, out object? result)
{
// result can be null
result = instance[binder.Name];
return true;
}
public override bool TrySetMember(JObject instance, SetMemberBinder binder, object value)
{View on GitHub (pinned to 4f73e74372)
Solutions
- Stop using 'dynamic' with JObject; access properties via the string indexer: jObject["SomeProperty"].
- Deserialize into typed POCOs with JsonConvert.DeserializeObject<T>.
- If dynamic access is essential, do not trim/AOT that path and set 'Newtonsoft.Json.Linq.JToken.DynamicIsSupported' to true in runtimeconfig.
Example fix
// before dynamic d = JObject.Parse(json); var name = d.Name; // NotSupportedException when trimmed // after var o = JObject.Parse(json); var name = (string)o["Name"]; // or var model = JsonConvert.DeserializeObject<MyModel>(json);
Defensive patterns
Strategy: validation
Validate before calling
bool dynamicSupported =
!AppContext.TryGetSwitch("Newtonsoft.Json.Linq.JToken.DynamicIsSupported", out bool enabled)
|| enabled;
if (!dynamicSupported)
throw new InvalidOperationException("Dynamic access on JObject is disabled under trimming."); Try / catch
try { dynamic d = jObject; var x = d.Name; }
catch (NotSupportedException ex) when (ex.Message.Contains("DynamicIsSupported"))
{
var x = (string)jObject["Name"];
} Prevention
- Do not use 'dynamic' with JObject; use the string indexer.
- Deserialize into typed POCOs in trimmed/AOT apps.
- If dynamic is required, do not trim and set the switch to true.
When it happens
Trigger: Using the C# 'dynamic' keyword (or any DLR binder) against a JObject — e.g. dynamic d = jObject; var x = d.SomeProperty; — in a trimmed/Native AOT app, or anywhere the switch 'Newtonsoft.Json.Linq.JToken.DynamicIsSupported' has been set to false.
Common situations: Publishing with trimming/Native AOT (the switch is flipped off), then writing dynamic d = JObject.Parse(json); accessing members dynamically; libraries that accept dynamic and forward JObjects.
Related errors
- Newtonsoft.Json support for System.ComponentModel is not com
- Argument is not a JToken.
- Could not determine new value to add to '{0}'.
- New item to be added to collection must be compatible with {
- Unexpected merge array handling when merging JSON.
AI-assisted analysis of JamesNK/Newtonsoft.Json@4f73e74372 (2026-08-07).
Data as JSON: /api/errors/060456a807066aa1.
Report an issue: GitHub.