hcengineering/platform · error
$size predicate requires array
Error message
$size predicate requires array
What it means
$size matches documents whose property is an array of a particular length. Unlike $in/$all/$nin, this check happens at evaluation time against the document's field value: when a matched document's property is not an array (or is a non-null scalar/object), predicate.ts throws this error while running the query. It indicates the queried field does not consistently hold arrays.
Source
Thrown at foundations/core/packages/core/src/predicate.ts:121
},
$lte: (o, propertyKey) => {
return (docs) => execPredicate(docs, propertyKey, (value) => value <= o)
},
$exists: (o, propertyKey) => {
return (docs) => execPredicate(docs, propertyKey, (value) => (value !== undefined) === o)
},
$ne: (o, propertyKey) => {
// eslint-disable-next-line eqeqeq
return (docs) => execPredicate(docs, propertyKey, (value) => (o != null ? !deepEqual(o, value) : value != null))
},
$size: (o, propertyKey) => {
return (docs) =>
execPredicate(docs, propertyKey, (value) => {
if (value == null) {
return false
}
if (!Array.isArray(value)) {
throw new Error('$size predicate requires array')
}
if (typeof o === 'number') {
return value.length === o
}
if (typeof o === 'object' && o.$gt !== undefined) {
return value.length > o.$gt
}
if (typeof o === 'object' && o.$gte !== undefined) {
return value.length >= o.$gte
}
if (typeof o === 'object' && o.$lt !== undefined) {
return value.length < o.$lt
}
if (typeof o === 'object' && o.$lte !== undefined) {
return value.length <= o.$lte
}
return false
})View on GitHub (pinned to 63e28dc964)
Solutions
- Fix the data so the field is always an array (migrate single values to [value]).
- Ensure write paths always assign arrays, even for one element.
- Pre-filter or $exists-guard the field, or use a different predicate ($exists, $ne) for non-array fields.
- Wrap query execution in try/catch if heterogeneous legacy data must be tolerated.
Example fix
// before (writer)
await update(doc, { $set: { attachments: file } })
// after
await update(doc, { $set: { attachments: [file] } }) Defensive patterns
Strategy: validation
Validate before calling
// Before querying with $size, ensure the field holds arrays everywhere
const bad = docs.find((d) => d.attachments != null && !Array.isArray(d.attachments))
if (bad != null) throw new Error(`doc ${bad._id} has non-array attachments; migrate before using $size`) Type guard
function hasArrayField<K extends string>(doc: Record<string, unknown>, key: K): doc is Record<K, unknown[]> {
return Array.isArray(doc[key])
} Try / catch
try {
return await find(clazz, { attachments: { $size: 3 } })
} catch (e) {
if (e instanceof Error && e.message.startsWith('$size predicate requires array')) {
// fall back: filter in code over non-array-tolerant predicate
const all = await find(clazz, { attachments: { $exists: true } })
return all.filter((d) => Array.isArray(d.attachments) && d.attachments.length === 3)
}
throw e
} Prevention
- Enforce array types on the field in every write path, even for single elements.
- Migrate legacy docs that store scalars/objects in the field before using $size.
- Prefer $exists/$ne predicates for fields that may be non-arrays.
When it happens
Trigger: Querying { attachments: { $size: 3 } } when some documents store attachments as undefined-is-guarded (returns false) but others store a scalar or a plain object (e.g. a single attachment object instead of an array) — evaluation then throws on those docs.
Common situations: Schema drift where older documents or imports stored the field as a single value; data written by another tool/version with a different shape; optional fields populated inconsistently across documents.
Related errors
- $in predicate requires array
- $all predicate requires array
- $nin predicate requires array
- unknown predicate:
- unknown operator: ${name}
AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29).
Data as JSON: /api/errors/ff501fa8680fa344.
Report an issue: GitHub.