JamesNK/Newtonsoft.Json · error · ArgumentOutOfRangeException

Index must be within the bounds of the List.

Error message

Index must be within the bounds of the List.

What it means

InsertItem throws ArgumentOutOfRangeException when the requested insertion index is strictly greater than ChildrenTokens.Count (index == Count is allowed for append; anything above is not). This guards the underlying List insert.

Source

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

                JsonCloneSettings? settings = copyAnnotations
                    ? null
                    : JsonCloneSettings.SkipCopyAnnotations;

                item = item.CloneToken(settings);
            }

            return item;
        }

        internal abstract int IndexOfItem(JToken? item);

        internal virtual bool InsertItem(int index, JToken? item, bool skipParentCheck, bool copyAnnotations)
        {
            IList<JToken> children = ChildrenTokens;

            if (index > children.Count)
            {
                throw new ArgumentOutOfRangeException(nameof(index), "Index must be within the bounds of the List.");
            }

            CheckReentrancy();

            item = EnsureParentToken(item, skipParentCheck, copyAnnotations);

            JToken? previous = (index == 0) ? null : children[index - 1];
            // haven't inserted new token yet so next token is still at the inserting index
            JToken? next = (index == children.Count) ? null : children[index];

            ValidateToken(item, null);

            item.Parent = this;

            item.Previous = previous;
            if (previous != null)
            {
                previous.Next = item;

View on GitHub (pinned to 4f73e74372)

Solutions

  1. To append, call Add(item) instead of Insert(Count, item) — or pass exactly Count.
  2. Clamp index to Math.Min(index, container.Count) before inserting.
  3. Recompute Count immediately before the insert when the collection may have changed.

Example fix

// before
arr.Insert(arr.Count + 1, item);
// after
arr.Add(item);
Defensive patterns

Strategy: validation

Validate before calling

int idx = Math.Min(requestedIndex, arr.Count);
arr.Insert(idx, item); // or arr.Add(item) to append

Try / catch

try { arr.Insert(index, item); }
catch (ArgumentOutOfRangeException ex) when (ex.ParamName == "index") {
    arr.Add(item); // append as a safe fallback
}

Prevention

When it happens

Trigger: jArray.Insert(index, item) where index > Count; Insert via IList<JToken>.Insert with a stale count; off-by-one after a concurrent removal.

Common situations: Off-by-one when inserting at 'the end' using count+1; using a cached count that is now stale; concurrent mutation.

Related errors


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