Automattic/mongoose · error · Error
Can't use ${$conditional} with Array.
Error message
Can't use ${$conditional} with Array. What it means
castForQuery on an array path dispatches the query operator to the array type's $conditionalHandlers; an operator with no handler (unsupported at field level for arrays, or a typo like $in2) throws immediately instead of sending an uncastable filter to the server.
Source
Thrown at lib/schema/array.js:544
return val;
};
/**
* Casts values for queries.
*
* @param {string} $conditional
* @param {any} [value]
* @api private
*/
SchemaArray.prototype.castForQuery = function($conditional, val, context) {
let handler;
if ($conditional != null) {
handler = this.$conditionalHandlers[$conditional];
if (!handler) {
throw new Error('Can\'t use ' + $conditional + ' with Array.');
}
return handler.call(this, val, context);
} else {
return this._castForQuery(val, context);
}
};
/**
* Add a virtual to this array. Specifically to this array, not the individual elements.
*
* @param {string} name
* @param {object} [options]
* @api private
*/
SchemaArray.prototype.virtual = function virtual(name, options) {
if (name instanceof VirtualType || getConstructorName(name) === 'VirtualType') {View on GitHub (pinned to 49cdab0136)
Solutions
- Use operators the array type registers (e.g. $in, $nin, $ne, $all, $elemMatch, $options, geo handlers on geo arrays).
- Match elements via $elemMatch: `{ tags: { $elemMatch: { $regex: /^x/ } } }` or dot-notation element queries.
- Fix operator typos - the message contains the exact operator string.
Example fix
// before
Model.find({ tags: { $regex: /^admin/ } });
// after
Model.find({ tags: { $elemMatch: { $regex: /^admin/ } } });
// or exact-element match:
Model.find({ tags: 'admin' }); Defensive patterns
Strategy: validation
Validate before calling
const ARRAY_FIELD_OPERATORS = new Set(['$in', '$nin', '$ne', '$all', '$elemMatch', '$options', '$size', '$exists', '$near', '$nearSphere', '$geoWithin', '$geoIntersects']);
const assertArrayFieldFilter = (filter) => {
for (const [k, v] of Object.entries(filter)) {
if (k.startsWith('$') && !ARRAY_FIELD_OPERATORS.has(k)) {
throw new Error(`operator ${k} is not supported directly on an array field`);
}
}
}; Prevention
- Prefer $elemMatch for element-level predicates on array paths.
- Keep a shared allow-list of operators your query builder emits and test filters against a local mongoose instance.
- The message echoes the operator verbatim - read it to catch typos like $in2.
When it happens
Trigger: `Model.find({ tags: { $regex: 'x' } })` where tags: [String] - $regex has no array-level handler; `{ nums: { $nearSphere: [1,2] } }` on a non-geo array; a misspelled operator echoed verbatim in the message.
Common situations: Porting scalar-field query syntax onto array fields; assuming every MongoDB operator is valid per-field; operators that only work at the filter's top level used under a field.
Related errors
- Cast to [${e.kind}] failed for value "${value}" (type ${valu
- Cast to Array failed for value "${value}" (type ${valueType}
- conditional ${op} requires an array
- Can't use ${conditional} with String.
- Can't use ${conditional}
AI-assisted analysis of Automattic/mongoose@49cdab0136 (2026-08-21).
Data as JSON: /api/errors/eda87f0e9278c4bf.
Report an issue: GitHub.