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

  1. Stop using 'dynamic' with JObject; access properties via the string indexer: jObject["SomeProperty"].
  2. Deserialize into typed POCOs with JsonConvert.DeserializeObject<T>.
  3. 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

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


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