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 JToken.GetMetaObject (the IDynamicMetaObjectProvider entry point) when the runtime tries to bind dynamic operations (dynamic keyword, ExpandoObject-style member access) on a JToken but the feature switch Newtonsoft.Json.Linq.JToken.DynamicIsSupported has been set to false. This switch is disabled automatically by the .NET trimmer/AOT analyser because dynamic dispatch relies on reflection over types that trimming removes, so it is a deliberate trim-safety gate. The message names the switch so the user knows exactly what to flip.

Source

Thrown at Src/Newtonsoft.Json/Linq/JToken.cs:2498

        {
            var p = new JPath(path);
            return p.Evaluate(this, this, settings);
        }

#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 virtual DynamicMetaObject GetMetaObject(Expression parameter)
        {
#if HAVE_APPCONTEXT
            if (!DynamicIsSupported)
            {
                throw new NotSupportedException(DynamicNotSupportedMessage);
            }
#endif
#pragma warning disable IL2026, IL3050
            return new DynamicProxyMetaObject<JToken>(parameter, this, new DynamicProxy<JToken>());
#pragma warning restore IL2026, IL3050
        }

        /// <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>
        DynamicMetaObject IDynamicMetaObjectProvider.GetMetaObject(Expression parameter)
        {
            return GetMetaObject(parameter);
        }

View on GitHub (pinned to 4f73e74372)

Solutions

  1. Stop using dynamic against JToken: cast to a strongly typed POCO via token.ToObject<T>() or use explicit indexing (token['prop']).
  2. If dynamic is mandatory on a non-trimmed build, set the AppContext switch Newtonsoft.Json.Linq.JToken.DynamicIsSupported=true (and disable trimming/AOT for that assembly).
  3. Disable PublishTrimmed / PublishSingleFile trimming for the process, or use a library build that excludes the dynamic guard.

Example fix

// before
dynamic dyn = JObject.Parse(json);
Console.WriteLine(dyn.user.name);

// after (AOT/trim safe)
var doc = JObject.Parse(json);
Console.WriteLine(doc["user"]?["name"]);
// or strongly typed
var user = doc.ToObject<User>();
Defensive patterns

Strategy: validation

Validate before calling

// Avoid dynamic entirely on trimmed builds; index explicitly
var v = doc["prop"]?.ToString();

Type guard

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

Try / catch

try { dynamic d = token; var x = d.prop; } catch (NotSupportedException) { /* fall back to indexer */ }

Prevention

When it happens

Trigger: Declaring dynamic dyn = JObject.Parse(json); then dyn.someProperty, in an app published with PublishTrimmed=true, PublishAot=true, or with the AppContext switch Newtonsoft.Json.Linq.JToken.DynamicIsSupported=false set explicitly. Also surfaced when the trim analyser statically sees dynamic usage and the runtime guards trip.

Common situations: Migrating a desktop app to .NET 6+ Native AOT or a trimmed self-contained deployment. Publishing Blazor WASM or MAUI with trimming enabled. Setting the switch to false manually after seeing IL2026/IL3050 trim warnings. Using the dynamic keyword heavily with LINQ-to-JSON and then trimming.

Related errors


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