mongodb/mongoid · error · Mongoid::Errors::InvalidQuery
$not argument cannot be an empty hash: #
Error message
$not argument cannot be an empty hash: #{Errors::InvalidQuery.truncate_expr(condition)} What it means
Raised inside Mongoid::Matcher::Not.matches? when an $not condition is given as a Hash that contains no keys. The matcher dispatches on the condition type: a Regexp is negated directly, while a Hash is expected to hold one or more query operator entries (keys starting with '$') whose matches are negated. An empty hash is rejected by this guard because there are no operators to negate, which would make the match result ambiguous (vacuously true in Ruby's all? but semantically meaningless as a query), and the server itself rejects {} as an $not argument. The input at fault is the condition argument — a caller-written or programmatically built $not clause like {"$not" => {}}. Note this is a sibling guard to the ones rejecting non-operator keys and non-Hash/non-Regexp conditions in the same method.
Solutions
- Provide at least one operator condition inside the $not hash
- Remove the $not clause if no negation is needed
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at lib/mongoid/matcher/not.rb:25 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/15b8c5be481548d6.
Report an issue: GitHub.
Appendix: source
Thrown at lib/mongoid/matcher/not.rb:25
# @api private
module Not
# Returns whether a value satisfies an $not expression.
#
# @param [ true | false ] exists Whether the value exists.
# @param [ Object ] value The value to check.
# @param [ Hash | Regexp | BSON::Regexp::Raw ] condition
# The $not condition predicate.
#
# @return [ true | false ] Whether the value matches.
#
# @api private
module_function def matches?(exists, value, condition)
case condition
when ::Regexp, BSON::Regexp::Raw
!Regex.matches?(exists, value, condition)
when Hash
if condition.empty?
raise Errors::InvalidQuery, "$not argument cannot be an empty hash: #{Errors::InvalidQuery.truncate_expr(condition)}"
end
condition.all? do |(k, cond_v)|
k = k.to_s
unless k.start_with?('$')
raise Errors::InvalidQuery, "$not arguments must be operators: #{Errors::InvalidQuery.truncate_expr(k)}"
end
!FieldOperator.get(k).matches?(exists, value, cond_v)
end
else
raise Errors::InvalidQuery, "$not argument must be a Hash or a regular expression: #{Errors::InvalidQuery.truncate_expr(condition)}"
end
end
end
end
end
View on GitHub (pinned to 0da0e23d71)