JamesNK/Newtonsoft.Json · error · ArgumentOutOfRangeException

Index is less than 0.

Error message

Index is less than 0.

What it means

RemoveItemAt throws ArgumentOutOfRangeException when the index passed to RemoveAt is negative. The method validates index < 0 before touching the child list.

Source

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

            }
#endif
#if HAVE_INOTIFY_COLLECTION_CHANGED
            if (_collectionChanged != null)
            {
                OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item, index));
            }
#endif

            return true;
        }

        internal virtual void RemoveItemAt(int index)
        {
            IList<JToken> children = ChildrenTokens;

            if (index < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(index), "Index is less than 0.");
            }
            if (index >= children.Count)
            {
                throw new ArgumentOutOfRangeException(nameof(index), "Index is equal to or greater than Count.");
            }

            CheckReentrancy();

            JToken item = children[index];
            JToken? previous = (index == 0) ? null : children[index - 1];
            JToken? next = (index == children.Count - 1) ? null : children[index + 1];

            if (previous != null)
            {
                previous.Next = next;
            }
            if (next != null)
            {

View on GitHub (pinned to 4f73e74372)

Solutions

  1. Guard the index: only call RemoveAt when index >= 0.
  2. Check the result of IndexOf for -1 (not found) before removing.
  3. Use Remove(item) which safely returns false when the item is absent.

Example fix

// before
arr.RemoveAt(arr.IndexOf(item));
// after
arr.Remove(item);
Defensive patterns

Strategy: validation

Validate before calling

if (index < 0) throw new ArgumentOutOfRangeException(nameof(index));
arr.RemoveAt(index);

Try / catch

try { arr.RemoveAt(index); }
catch (ArgumentOutOfRangeException ex) when (ex.ParamName == "index") {
    // index was invalid; ignore or report
}

Prevention

When it happens

Trigger: jArray.RemoveAt(-1); a computed index that underflows to negative; RemoveAt on an index derived from IndexOf returning -1.

Common situations: Using IndexOfItem result (-1 when not found) directly as a remove index; arithmetic that goes below zero.

Related errors


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