gatsbyjs/gatsby · error

The argument to the `in` comparator should be an array

Error message

The argument to the `in` comparator should be an array

What it means

The `in` comparator (`filter: { field: { in: [...] } }`) is implemented in the in-memory datastore runner and requires its value to be an Array. A scalar is rejected before bucket lookup because there is no single-value fast path for `in`.

Source

Thrown at packages/gatsby/src/datastore/in-memory/indexing.ts:706

    if (filterValue == null) {
      // Edge case for null; fetch all nodes for `null` and `undefined` because
      // `$eq` also returns nodes without the path when searching for `null`.
      // Not all ops do so, so we map non-existing paths to `undefined`.

      const arrNull = filterCache.byValue.get(null) ?? []
      const arrUndef = filterCache.byValue.get(undefined) ?? []

      // Merge the two (ordered) arrays and return an ordered deduped array
      // TODO: is there a reason left why we cant just cache this merged list?
      return unionNodesByCounter(arrNull, arrUndef)
    }

    return filterCache.byValue.get(filterValue)
  }

  if (op === `$in`) {
    if (!Array.isArray(filterValue)) {
      throw new Error("The argument to the `in` comparator should be an array")
    }
    const filterValueArr: Array<FilterValueNullable> = filterValue

    const set: Set<IGatsbyNodePartial> = new Set()

    // TODO: we can also mergeSort for every step. this may perform worse because of how memory in js works.
    // For every value in the needle array, find the bucket of nodes for
    // that value, add this bucket of nodes to one list, return the list.
    filterValueArr.forEach((v: FilterValueNullable) =>
      filterCache.byValue.get(v)?.forEach(v => set.add(v))
    )

    const arr = [...set] // this is bad for perf but will guarantee us a unique set :(
    arr.sort(sortByIds)

    // Note: it's very unlikely that the list of filter values is big so .includes should be fine here
    if (filterValueArr.includes(null)) {
      // Like all other ops, `in: [null]` behaves weirdly, allowing all nodes

View on GitHub (pinned to 8b06340921)

Solutions

  1. Wrap the value in an array: `in: ["abc"]`.
  2. Type the GraphQL variable as a list, e.g. `[ID]!`.
  3. Normalise at the caller so the value is always an array.

Example fix

// before
filter: { id: { in: "abc" } }
// after
filter: { id: { in: ["abc"] } }
Defensive patterns

Strategy: type-guard

Validate before calling

function asArray<T>(v: T | T[]): T[] { return Array.isArray(v) ? v : [v] }
// then: filter: { id: { in: asArray(ids) } }

Type guard

function isInFilterValue(v: unknown): v is unknown[] { return Array.isArray(v) }

Prevention

When it happens

Trigger: Writing `filter: { id: { in: "abc" } }` or passing a variable that resolved to a non-array.

Common situations: Passing a single id instead of a list; GraphQL variable typed as `ID` instead of `[ID]`; client code that sometimes returns one value.

Related errors


AI-assisted analysis of gatsbyjs/gatsby@8b06340921 (2026-08-13). Data as JSON: /api/errors/48332934cded8573. Report an issue: GitHub.