mongodb/mongoid · error · Mongoid::Errors::InvalidQuery
# argument must be an array: #
Error message
#{operator} argument must be an array: #{Errors::InvalidQuery.truncate_expr(op_expr)} What it means
add_logical_operator_expression validates the pieces of a $and/$or/$nor clause: the operator must be one of those three strings and its value must be an Array of sub-expressions. A non-array value fails this guard with the truncated expression shown.
Solutions
- Pass logical operator values as arrays of hashes, e.g. [ { a: 1 }, { b: 2 } ]
- Build $or/$and via any_of/all so the shape is constructed correctly
Defensive patterns
Strategy: type-guard
When it happens
Trigger: Thrown at lib/mongoid/criteria/queryable/storable.rb:110 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of mongodb/mongoid@0da0e23d71 (2026-08-23).
Data as JSON: /api/errors/44bfb0300dd78645.
Report an issue: GitHub.
Appendix: source
Thrown at lib/mongoid/criteria/queryable/storable.rb:110
# Such simplification is also expected to have already been performed
# by the upstream code.
#
# This method mutates the receiver.
#
# @param [ String ] operator The operator to add.
# @param [ Array<Hash> ] op_expr Operator value to add.
#
# @return [ Storable ] self.
def add_logical_operator_expression(operator, op_expr)
raise ArgumentError, "Operator must be a string: #{operator}" unless operator.is_a?(String)
unless %w[$and $nor $or].include?(operator)
raise ArgumentError,
"This method only handles logical operators ($and, $nor, $or). Operator given: #{operator}"
end
unless op_expr.is_a?(Array)
raise Errors::InvalidQuery, "#{operator} argument must be an array: #{Errors::InvalidQuery.truncate_expr(op_expr)}"
end
if selector.length == 1 && selector.keys.first == operator
new_value = selector.values.first + op_expr
selector.store(operator, new_value)
elsif operator == '$and' || selector.empty?
# $and can always be added to top level and it will be combined
# with whatever other conditions exist.
if current_value = selector[operator]
new_value = current_value + op_expr
selector.store(operator, new_value)
else
selector.store(operator, op_expr)
end
elsif selector[operator]
# Other operators need to be added separately
add_logical_operator_expression('$and', [ { operator => op_expr } ])
elseView on GitHub (pinned to 0da0e23d71)