gatsbyjs/gatsby · error · Error
${filter.comparator} value must not be an array
Error message
${filter.comparator} value must not be an array What it means
For `lt`/`lte` index range planning, the filter value must be a scalar so a single range boundary can be computed. An array is rejected because it would imply multiple boundaries that `lt`/`lte` cannot represent.
Source
Thrown at packages/gatsby/src/datastore/lmdb/query/filter-using-index.ts:541
let hasNull = false
for (const item of new Set(arr)) {
const value = toIndexFieldValue(item, filter)
if (value === null) hasNull = true
rangeStarts.push(value)
rangeEndings.push(getValueEdgeAfter(value))
}
// Special case: { eq: null } or { in: [null, `any`]} must also include values for undefined!
if (hasNull) {
rangeStarts.push(undefinedSymbol)
rangeEndings.push(getValueEdgeAfter(undefinedSymbol))
}
break
}
case DbComparator.LT:
case DbComparator.LTE: {
if (Array.isArray(filter.value))
throw new Error(`${filter.comparator} value must not be an array`)
const value = toIndexFieldValue(filter.value, filter)
const end =
filter.comparator === DbComparator.LT ? value : getValueEdgeAfter(value)
// Try to find matching GTE/GT filter
const start =
resolveRangeEdge(context, field, DbComparator.GTE) ??
resolveRangeEdge(context, field, DbComparator.GT, ValueEdges.AFTER)
// Do not include null or undefined in results unless null was requested explicitly
//
// Index ordering:
// BinaryInfinityNegative
// null
// Symbol(`undef`)
// -10
// 10View on GitHub (pinned to 8b06340921)
Solutions
- Pass a single scalar to `lt`/`lte`.
- Use `in`/`nin` or split into multiple queries if a set of upper bounds is needed.
Example fix
// before
filter: { age: { lt: [10, 20] } }
// after
filter: { age: { lt: 20 } } Defensive patterns
Strategy: validation
Validate before calling
function assertScalarRange(op, value) {
if (["lt", "lte"].includes(op) && Array.isArray(value)) {
throw new Error(`${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
- Pass single scalars to `lt`/`lte`/`gt`/`gte`.
- Centralise filter construction with per-operator validators.
When it happens
Trigger: `filter: { age: { lt: [10, 20] } }` against an indexed field.
Common situations: Variable reuse; building filters generically and always wrapping values in arrays.
Related errors
- The argument to the `in` predicate should be an array
- Range filter ${predicate} should not have array value
- 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/4703e685a95ef14a.
Report an issue: GitHub.