meteor/meteor · error · MiniMongoQueryError

no $ expressions in $all

Error message

no $ expressions in $all

What it means

Thrown by the $all operator when any criterion inside the operand array is itself an operator object. The comment notes that $all/$elemMatch combination is not handled (XXX); $all only accepts equality values or RegExp, so $gt/$ne/etc. inside $all is rejected via isOperatorObject.

Source

Thrown at packages/minimongo/common.js:386

      throw new MiniMongoQueryError('$maxDistance needs a $near');
    }

    return everythingMatcher;
  },
  $all(operand, valueSelector, matcher) {
    if (!Array.isArray(operand)) {
      throw new MiniMongoQueryError('$all requires array');
    }

    // Not sure why, but this seems to be what MongoDB does.
    if (operand.length === 0) {
      return nothingMatcher;
    }

    const branchedMatchers = operand.map(criterion => {
      // XXX handle $all/$elemMatch combination
      if (isOperatorObject(criterion)) {
        throw new MiniMongoQueryError('no $ expressions in $all');
      }

      // This is always a regexp or equality selector.
      return compileValueSelector(criterion, matcher);
    });

    // andBranchedMatchers does NOT require all selectors to return true on the
    // SAME branch.
    return andBranchedMatchers(branchedMatchers);
  },
  $near(operand, valueSelector, matcher, isRoot) {
    if (!isRoot) {
      throw new MiniMongoQueryError('$near can\'t be inside another $ operator');
    }

    matcher._hasGeoQuery = true;

    // There are two kinds of geodata in MongoDB: legacy coordinate pairs and

View on GitHub (pinned to 5076d2f818)

Solutions

  1. Use plain equality values in $all: {field: {$all: ['a', 'b']}}.
  2. For operator-based element matching across an array, use $elemMatch at the field level instead of nesting in $all.
  3. For RegExp membership, $all does accept RegExp instances: {field: {$all: [/^a/]}}.

Example fix

// before
collection.find({ tags: { $all: [{$gt: 'a'}] } });
// after
collection.find({ tags: { $all: ['b', 'c'] } });
Defensive patterns

Strategy: validation

Validate before calling

function buildAllSelector(values) {
  const bad = values.filter(v => v !== null && typeof v === 'object' && !(v instanceof RegExp) && Object.keys(v).some(k => k.startsWith('$')));
  if (bad.length) throw new Error('$all does not support nested operators');
  return { $all: values };
}

Type guard

function isPlainAllElement(el) {
  return el instanceof RegExp || el === null || typeof el !== 'object' || Object.keys(el).every(k => !k.startsWith('$'));
}

Prevention

When it happens

Trigger: Using {field: {$all: [{$gt: 5}]}} or {field: {$all: [{$elemMatch: {...}}]}} in a minimongo query. Each element is checked with isOperatorObject.

Common situations: Trying to require that an array contains an element matching a sub-query; copying a MongoDB example that uses $elemMatch inside $all (minimongo does not support that combination); merging selectors that inject operators.

Related errors


AI-assisted analysis of meteor/meteor@5076d2f818 (2026-08-13). Data as JSON: /api/errors/85da75b07b132458. Report an issue: GitHub.