JamesNK/Newtonsoft.Json · error · JsonException

Index outside the bounds of JArray.

Error message

Index {0} outside the bounds of JArray.

What it means

Thrown by PathFilter.GetTokenIndex when an array index applied to a JArray is greater than or equal to the array's Count, but only when JsonSelectSettings.ErrorWhenNoMatch is true. Without that flag the filter silently returns null (no match).

Solutions

  1. Check the array length before indexing, or omit ErrorWhenNoMatch so out-of-range indices yield no token instead of throwing.
  2. Use array slice or scan filters ($..) instead of absolute indices when length is variable.
  3. Validate payload shape (e.g. minimum array length) before running the path.

Example fix

// before
token.SelectTokens("$.items[10]", new JsonSelectSettings { ErrorWhenNoMatch = true });
// after
var arr = (JArray)token["items"];
if (arr.Count > 10)
{
    token.SelectTokens("$.items[10]", new JsonSelectSettings { ErrorWhenNoMatch = true });
}
Defensive patterns

Strategy: validation

Validate before calling

static bool CanIndex(JToken token, int index)
{
    return token is JArray a && index >= 0 && index < a.Count;
}

Type guard

bool IsIndexableArray(JToken t) => t is JArray && t.HasValues;

Try / catch

try { token.SelectTokens("$.items[10]", settings).ToList(); }
catch (JsonException ex) when (ex.Message.Contains("outside the bounds of JArray"))
{ /* index too large; degrade gracefully */ }

Prevention

When it happens

Trigger: Calling SelectTokens with ErrorWhenNoMatch=true and an index that exceeds the array size. Example: token.SelectTokens("$.items[10]", new JsonSelectSettings { ErrorWhenNoMatch = true }) on an array with fewer than 11 elements.

Common situations: Hard-coded indices assuming a minimum payload size; payloads that changed shape between environments; negative-or-zero-length arrays from an upstream service outage; enabling ErrorWhenNoMatch to get strict behavior and then hitting variable-length data.

Related errors


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

Appendix: source

Thrown at Src/Newtonsoft.Json/Linq/JsonPath/PathFilter.cs:19

using System.Collections.Generic;
using System.Globalization;
using Newtonsoft.Json.Utilities;

namespace Newtonsoft.Json.Linq.JsonPath
{
    internal abstract class PathFilter
    {
        public abstract IEnumerable<JToken> ExecuteFilter(JToken root, IEnumerable<JToken> current, JsonSelectSettings? settings);

        protected static JToken? GetTokenIndex(JToken t, JsonSelectSettings? settings, int index)
        {
            if (t is JArray a)
            {
                if (a.Count <= index)
                {
                    if (settings?.ErrorWhenNoMatch ?? false)
                    {
                        throw new JsonException("Index {0} outside the bounds of JArray.".FormatWith(CultureInfo.InvariantCulture, index));
                    }

                    return null;
                }

                return a[index];
            }
            else if (t is JConstructor c)
            {
                if (c.Count <= index)
                {
                    if (settings?.ErrorWhenNoMatch ?? false)
                    {
                        throw new JsonException("Index {0} outside the bounds of JConstructor.".FormatWith(CultureInfo.InvariantCulture, index));
                    }

                    return null;
                }

View on GitHub (pinned to 4f73e74372)