JamesNK/Newtonsoft.Json · error · ArgumentException

Can not add {0} to {1}.

Error message

Can not add {0} to {1}.

What it means

ValidateToken throws ArgumentException when you attempt to add a JProperty token to a non-object container (a JArray or JConstructor). JProperty is only valid as a child of JObject; arrays and constructors hold values, not name/value pairs.

Source

Thrown at Src/Newtonsoft.Json/Linq/JContainer.cs:638

                if (newValue == null)
                {
                    // null will get turned into a JValue of type null
                    return v1.Type == JTokenType.Null;
                }

                return v1.Equals(newValue);
            }

            return false;
        }

        internal virtual void ValidateToken(JToken o, JToken? existing)
        {
            ValidationUtils.ArgumentNotNull(o, nameof(o));

            if (o.Type == JTokenType.Property)
            {
                throw new ArgumentException("Can not add {0} to {1}.".FormatWith(CultureInfo.InvariantCulture, o.GetType(), GetType()));
            }
        }

        /// <summary>
        /// Adds the specified content as children of this <see cref="JToken"/>.
        /// </summary>
        /// <param name="content">The content to be added.</param>
        public virtual void Add(object? content)
        {
            TryAddInternal(ChildrenTokens.Count, content, false, copyAnnotations: true);
        }

        internal bool TryAdd(object? content)
        {
            return TryAddInternal(ChildrenTokens.Count, content, false, copyAnnotations: true);
        }

        internal void AddAndSkipParentCheck(JToken token)

View on GitHub (pinned to 4f73e74372)

Solutions

  1. Add the property's Value (not the JProperty) to a JArray: jArray.Add(prop.Value).
  2. Add JProperty nodes only to a JObject.
  3. If you need name/value pairs, build a JObject, not a JArray.

Example fix

// before
jArray.Add(new JProperty("id", 1));
// after
jArray.Add(1);
// or, for named pairs, use a JObject:
// jObject.Add(new JProperty("id", 1));
Defensive patterns

Strategy: validation

Validate before calling

if (token is JProperty prop) {
    // unwrap for non-object containers, or add to a JObject
    jArray.Add(prop.Value);
} else {
    jArray.Add(token);
}

Type guard

static bool IsValidArrayChild(JToken t) => t.Type != JTokenType.Property;

Try / catch

try { jArray.Add(token); }
catch (ArgumentException ex) when (ex.Message.StartsWith("Can not add")) {
    // token was a JProperty: add its value instead
    if (token is JProperty p) jArray.Add(p.Value);
}

Prevention

When it happens

Trigger: jArray.Add(new JProperty("k", 1)); inserting a JProperty via InsertItem into a JArray/JConstructor.

Common situations: Generic tree-building code that adds JProperty nodes indiscriminately; converting object subtrees into array children without unwrapping.

Related errors


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