{"record":{"id":"8606ae320503ab19","repo":"redis/redis-rb","slug":"value-is-required-for-the-match-operation","errorCode":null,"errorMessage":"value is required for the MATCH operation","messagePattern":"value is required for the MATCH operation","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"lib/redis/commands/arrays.rb","lineNumber":322,"sourceCode":"      #   redis.arop(\"foo\", 0, 9, :sum)\n      #     # => 6.0\n      # @example Count elements equal to a value\n      #   redis.arop(\"foo\", 0, 9, :match, value: \"2\")\n      #     # => 1\n      #\n      # @param [String] key\n      # @param [Integer] start zero-based index of the first element (inclusive);\n      #   the range is always scanned from the lower to the higher index\n      # @param [Integer] stop zero-based index of the last element (inclusive)\n      # @param [Symbol, String] operation one of `:sum`, `:min`, `:max`,\n      #   `:and`, `:or`, `:xor`, `:match`, `:used`\n      # @param [String] value the value to compare against (required for `:match`)\n      # @return [Float, Integer, nil] the aggregate result — a Float for\n      #   `:sum`/`:min`/`:max`, an Integer otherwise; `nil` when no elements\n      #   qualify\n      def arop(key, start, stop, operation, value: nil)\n        operation = operation.to_s.upcase\n        raise ArgumentError, \"value is required for the MATCH operation\" if operation == \"MATCH\" && value.nil?\n\n        args = [:arop, key, Integer(start), Integer(stop), operation]\n        args << value if operation == \"MATCH\"\n\n        if %w[SUM MIN MAX].include?(operation)\n          send_command(args, &Floatify)\n        else\n          send_command(args)\n        end\n      end\n\n      # Get metadata about an array.\n      #\n      # @param [String] key\n      # @param [Boolean] full include per-slice statistics\n      # @return [Hash{String => Integer, Float}] metadata fields such as\n      #   `count`, `len`, `next-insert-index` and `slices`; with `full:` the\n      #   `avg-*` slice statistics are returned as `Float`","sourceCodeStart":304,"sourceCodeEnd":340,"githubUrl":"https://github.com/redis/redis-rb/blob/2ba9010b91dab9e0fde1fbae3a9aae003f8bc307/lib/redis/commands/arrays.rb#L304-L340","documentation":"arop sends an aggregate operation over an index range. MATCH is a filter that compares each element against a reference value, so the value: keyword is mandatory for it: the operation is upcased and compared to 'MATCH', and a nil value raises ArgumentError 'value is required for the MATCH operation'. Numeric aggregates (SUM/MIN/MAX, etc.) never take a value.","triggerScenarios":"redis.arop('k', 0, -1, :match) or operation: 'match' without value:; forwarding value conditionally (value: cond ? x : nil) so it ends up nil; a generic wrapper that always passes operation but only sometimes value.","commonSituations":"Aggregation DSLs where the operation is a variable; case/when dispatch that forgets to forward value; porting code from a numeric op to MATCH without adding the value.","solutions":["Pass the comparison value: redis.arop(key, start, stop, :match, value: 'x')","If no comparison value exists, use a numeric operation (sum/min/max) instead of match","Validate upfront when the operation is dynamic: raise if it case-matches 'match' and value is nil"],"exampleFix":"# before\nredis.arop('foo', 0, -1, :match)  # ArgumentError\n\n# after\nredis.arop('foo', 0, -1, :match, value: 'target')","handlingStrategy":"validation","validationCode":"if operation.to_s.casecmp('match').zero? && value.nil?\n  raise ArgumentError, 'value is required for match'\nend\nredis.arop(key, start, stop, operation, value: value)","typeGuard":"def needs_value?(operation)\n  operation.to_s.casecmp('match').zero?\nend","tryCatchPattern":null,"preventionTips":["Forward the value: keyword in every code path that can pass :match","Default value to a sentinel you validate, not nil, when the operation is dynamic","Document that numeric aggregates take no value"],"tags":["argument-validation","missing-argument","arrays"],"backgroundTag":"missing-required-argument","analyzedSha":"2ba9010b91dab9e0fde1fbae3a9aae003f8bc307","analyzedAt":"2026-08-23T03:54:57.017Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}