gatsbyjs/gatsby · error · Error

Range filter should not have array value

Error message

Range filter ${predicate} should not have array value

What it means

While resolving a complementary range edge (e.g. looking up a `gt` when planning an `lt`), `resolveRangeEdge` finds an unused filter statement for the same predicate whose value is an Array. Range predicates require scalar values, so it throws with the predicate name.

Solutions

  1. Make every range predicate (`gt`/`gte`/`lt`/`lte`) a scalar.
  2. Audit the filter object literal for stray array values.

Example fix

// before
filter: { age: { lt: 30 }, age: { gt: [10, 20] } }
// after
filter: { age: { lt: 30 }, age: { gt: 10 } }
Defensive patterns

Strategy: validation

Validate before calling

const RANGE = new Set(["lt", "lte", "gt", "gte"])
function validateRangeFilters(filter) {
  for (const ops of Object.values(filter)) {
  for (const [op, value] of Object.entries(ops)) {
  if (RANGE.has(op) && Array.isArray(value)) throw new Error(`Range ${op} must be scalar`)
  }
  }
}

Type guard

function isRangeScalar(v: unknown): v is string | number | boolean | null {
  return v === null || ["string", "number", "boolean"].includes(typeof v)
}

Prevention

When it happens

Trigger: Combining range filters where one of them carries an array value, e.g. `{ age: { lt: 30 }, age: { gt: [10, 20] } }`.

Common situations: Programmatic filter construction producing arrays for range operators.

Related errors


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

Appendix: source

Thrown at packages/gatsby/src/datastore/lmdb/query/filter-using-index.ts:647

function resolveRangeEdge(
  context: IFilterContext,
  indexField: string,
  predicate: DbComparator,
  edge: ValueEdges = ValueEdges.EQ
): IndexFieldValue | RangeEdgeBefore | RangeEdgeAfter | undefined {
  const fieldQueries = getFieldQueries(context.dbQueries, indexField)
  for (const dbQuery of fieldQueries) {
    if (context.usedQueries.has(dbQuery)) {
      continue
    }
    const filterStatement = getFilterStatement(dbQuery)
    if (filterStatement.comparator !== predicate) {
      continue
    }
    context.usedQueries.add(dbQuery)
    const value = filterStatement.value
    if (Array.isArray(value)) {
      throw new Error(`Range filter ${predicate} should not have array value`)
    }
    if (typeof value === `object` && value !== null) {
      throw new Error(
        `Range filter ${predicate} should not have value of type ${typeof value}`
      )
    }
    if (edge === 0) {
      return value
    }
    return edge < 0 ? getValueEdgeBefore(value) : getValueEdgeAfter(value)
  }
  return undefined
}

/**
 * Returns the edge after the given value, suitable for lmdb range queries.
 *
 * Example:

View on GitHub (pinned to 8b06340921)