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

  1. Provide at least one operator condition inside the $not hash
  2. 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)