JamesNK/Newtonsoft.Json · error · JsonException

Cannot add or remove items from {0}.

Error message

Cannot add or remove items from {0}.

What it means

A JProperty must always have exactly one value, so removing that value (rather than replacing it) is illegal. JProperty.RemoveItem (JProperty.cs:233) throws JsonException 'Cannot add or remove items from JProperty.' when something attempts to delete the property's sole child. To change the value you must assign a new one; to remove the whole property you remove the property from its parent JObject.

Source

Thrown at Src/Newtonsoft.Json/Linq/JProperty.cs:233

            {
                throw new ArgumentOutOfRangeException();
            }

            if (IsTokenUnchanged(Value, item))
            {
                return;
            }

            ((JObject?)Parent)?.InternalPropertyChanging(this);

            base.SetItem(0, item);

            ((JObject?)Parent)?.InternalPropertyChanged(this);
        }

        internal override bool RemoveItem(JToken? item)
        {
            throw new JsonException("Cannot add or remove items from {0}.".FormatWith(CultureInfo.InvariantCulture, typeof(JProperty)));
        }

        internal override void RemoveItemAt(int index)
        {
            throw new JsonException("Cannot add or remove items from {0}.".FormatWith(CultureInfo.InvariantCulture, typeof(JProperty)));
        }

        internal override int IndexOfItem(JToken? item)
        {
            if (item == null)
            {
                return -1;
            }

            return _content.IndexOf(item);
        }

        internal override bool InsertItem(int index, JToken? item, bool skipParentCheck, bool copyAnnotations)

View on GitHub (pinned to 4f73e74372)

Solutions

  1. To blank the value, set myProperty.Value = null (or JValue.CreateNull()) instead of removing the child.
  2. To delete the property entirely, call myProperty.Remove() (removes the property from its parent JObject) or parentObject.Remove("name").
  3. In generic tree pruning, skip the value inside a JProperty and act on the property itself.

Example fix

// before
var prop = (JProperty)obj.First;
prop.Value.Remove(); // throws JsonException: Cannot add or remove items from JProperty

// after — blank the value
prop.Value = null;
// after — delete the property from its parent
prop.Remove();
Defensive patterns

Strategy: validation

Validate before calling

// To blank a value: set Value = null. To delete the property: remove it from the parent.
if (token is JProperty p)
{
    p.Value = null;       // blank, keep property
    // or p.Remove();      // delete property from its JObject
}

Type guard

static bool HasParent(JToken t) => t?.Parent != null;

Try / catch

try { prop.Value.Remove(); }
catch (JsonException) { /* set Value instead */ prop.Value = null; }

Prevention

When it happens

Trigger: Calling .Remove() on the value token held by a property (e.g. myProperty.Value.Remove() or myProperty.First.Remove()), or invoking Remove(item) on the property's child collection through JContainer APIs.

Common situations: Walking a parsed JSON tree and calling Remove() on leaf nodes generically; conditional deletion logic that tries to null out a property by deleting its value instead of setting Value = null or removing the property from the owning object.

Related errors


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