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
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.
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…
- Accessed JObject values with invalid key value
- Argument is not a JToken.
- array
- arrayIndex is equal to or greater than the length of array.
AI-assisted analysis of JamesNK/Newtonsoft.Json@4f73e74372 (2026-08-07).
Data as JSON: /api/errors/060456a807066aa1.
Report an issue: GitHub.
Appendix: 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)