JamesNK/Newtonsoft.Json · error · ArgumentException

Can not add {0} to {1}.

Error message

Can not add {0} to {1}.

What it means

ArgumentException thrown by JObject.ValidateToken when attempting to add a JToken that is not a JProperty. JObject may only contain JProperty children; adding any other token type (a JValue, JObject, JArray, or a literal wrapped via JValue) is rejected.

Source

Thrown at Src/Newtonsoft.Json/Linq/JObject.cs:160

        internal override bool InsertItem(int index, JToken? item, bool skipParentCheck, bool copyAnnotations)
        {
            // don't add comments to JObject, no name to reference comment by
            if (item != null && item.Type == JTokenType.Comment)
            {
                return false;
            }

            return base.InsertItem(index, item, skipParentCheck, copyAnnotations);
        }

        internal override 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()));
            }

            JProperty newProperty = (JProperty)o;

            if (existing != null)
            {
                JProperty existingProperty = (JProperty)existing;

                if (newProperty.Name == existingProperty.Name)
                {
                    return;
                }
            }

            if (_properties.TryGetValue(newProperty.Name, out existing))
            {
                throw new ArgumentException("Can not add property {0} to {1}. Property with the same name already exists on object.".FormatWith(CultureInfo.InvariantCulture, newProperty.Name, GetType()));
            }

View on GitHub (pinned to 4f73e74372)

Solutions

  1. Wrap the value in a named property: jObject.Add(new JProperty("name", value)).
  2. Use the string-keyed Add overload: jObject.Add("name", value) which constructs the JProperty for you.
  3. Use the indexer jObject["name"] = value to set/replace a property.

Example fix

// before
jObject.Add(new JValue(42)); // ArgumentException

// after
jObject.Add("age", 42);
// or explicitly
jObject.Add(new JProperty("age", 42));
Defensive patterns

Strategy: type-guard

Validate before calling

static void AddProperty(JObject obj, string name, JToken value)
{
    var prop = value as JProperty ?? new JProperty(name, value);
    obj.Add(prop);
}

Type guard

static bool IsProperty(JToken? t) => t is JProperty;

Try / catch

try { jObject.Add(item); }
catch (ArgumentException ex) when (ex.Message.StartsWith("Can not add "))
{
    jObject.Add(new JProperty("item", item));
}

Prevention

When it happens

Trigger: Calling jObject.Add(new JValue(...)), jObject.Add(otherJObject), jObject.Add(jArray), ((IList<JToken>)jObject).Add(someValue), or JContainer.Add on a JObject with a non-JProperty item. Also triggered by jObject["key"] = someNonJToken routed through paths that build a property incorrectly.

Common situations: Treating a JObject like a JArray and pushing values directly; copying children from one container to a JObject without wrapping in JProperty; generic 'merge into object' helpers that add raw tokens.

Related errors


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