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

  1. Use operators the array type registers (e.g. $in, $nin, $ne, $all, $elemMatch, $options, geo handlers on geo arrays).
  2. Match elements via $elemMatch: `{ tags: { $elemMatch: { $regex: /^x/ } } }` or dot-notation element queries.
  3. 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

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


AI-assisted analysis of Automattic/mongoose@49cdab0136 (2026-08-21). Data as JSON: /api/errors/eda87f0e9278c4bf. Report an issue: GitHub.