gatsbyjs/gatsby · error · Error
Range filter ${predicate} 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.
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)
Solutions
- Make every range predicate (`gt`/`gte`/`lt`/`lte`) a scalar.
- 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
- Audit combined range filters for stray arrays.
- Use a typed filter builder that forbids arrays on range operators.
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
- The argument to the `in` predicate should be an array
- ${filter.comparator} value must not be an array
- Range filter ${predicate} should not have value of type ${ty
- Bad filter value for predicate ${filter.comparator}: ${inspe
- The $regex comparator is expecting the regex as a string, no
AI-assisted analysis of gatsbyjs/gatsby@8b06340921 (2026-08-13).
Data as JSON: /api/errors/7bc071514d86da19.
Report an issue: GitHub.