{"record":{"id":"d279ed655cf1650a","repo":"redis/redis-rb","slug":"logic-must-be-and-or-or","errorCode":null,"errorMessage":"logic must be :and or :or","messagePattern":"logic must be :and or :or","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"lib/redis/commands/arrays.rb","lineNumber":286,"sourceCode":"      # @param [String, Array<String>] exact match by exact equality\n      # @param [String, Array<String>] match match by substring\n      # @param [String, Array<String>] glob match by glob-style pattern (`*`, `?`, `[...]`)\n      # @param [String, Array<String>] re match by regular expression\n      # @param [Symbol] logic `:and` or `:or` — how multiple predicates combine (server default is OR)\n      # @param [Integer] limit stop after this many matches\n      # @param [Boolean] with_values return `[index, value]` pairs instead of indices\n      # @param [Boolean] nocase case-insensitive comparison for all predicates\n      # @return [Array<Integer>, Array<Array(Integer, String)>] matching\n      #   indices in traversal order, or `[index, value]` pairs with `with_values`\n      def argrep(key, start, stop, exact: nil, match: nil, glob: nil, re: nil,\n                 logic: nil, limit: nil, with_values: nil, nocase: nil)\n        args = [:argrep, key, argrep_bound(start), argrep_bound(stop)]\n        { \"EXACT\" => exact, \"MATCH\" => match, \"GLOB\" => glob, \"RE\" => re }.each do |predicate, values|\n          Array(values).each { |value| args << predicate << value }\n        end\n        if logic\n          operator = logic.to_s.upcase\n          raise ArgumentError, \"logic must be :and or :or\" unless %w[AND OR].include?(operator)\n\n          args << operator\n        end\n        args << \"LIMIT\" << Integer(limit) if limit\n        args << \"WITHVALUES\" if with_values\n        args << \"NOCASE\" if nocase\n        send_command(args)\n      end\n\n      # Perform an aggregate operation on the non-empty elements in a range.\n      #\n      # Supported operations: `:sum`, `:min`, `:max` (numeric, returned as\n      # Float), `:and`, `:or`, `:xor` (bitwise, floats truncated toward\n      # zero), `:match` (count of elements equal to `value`) and `:used`\n      # (count of non-empty elements).\n      #\n      # @example\n      #   redis.arop(\"foo\", 0, 9, :sum)","sourceCodeStart":268,"sourceCodeEnd":304,"githubUrl":"https://github.com/redis/redis-rb/blob/2ba9010b91dab9e0fde1fbae3a9aae003f8bc307/lib/redis/commands/arrays.rb#L268-L304","documentation":"argrep's optional logic: keyword combines the EXACT/MATCH/GLOB/RE predicates. The value is stringified and upcased, then must equal AND or OR; any other truthy value raises ArgumentError 'logic must be :and or :or'. Omitting the keyword (nil) sends no operator and is always safe.","triggerScenarios":"redis.argrep('k', 0, -1, match: 'x', logic: :xor); logic: 'NOT'; a variable defaulting to a flag name from another API (e.g. :all) passed straight through.","commonSituations":"Copy-pasting operator names from set operations or SQL; user-supplied filter parameters forwarded without whitelisting; typos like :nad or 'orr'.","solutions":["Pass only logic: :and or logic: :or (any case works — to_s.upcase is applied), or omit the keyword entirely","Whitelist user input before the call: accept it only when logic.to_s.downcase is 'and' or 'or', else drop it or raise your own error","Rescue ArgumentError and surface the allowed values to the caller/UI"],"exampleFix":"# before\nredis.argrep('foo', 0, -1, match: 'a*', logic: :xor)  # ArgumentError\n\n# after\nredis.argrep('foo', 0, -1, match: 'a*', logic: :or)","handlingStrategy":"type-guard","validationCode":"logic = %w[and or].include?(logic.to_s.downcase) ? logic : nil\nredis.argrep(key, start, stop, match: m, logic: logic)","typeGuard":"def valid_argrep_logic?(value)\n  %w[and or].include?(value.to_s.downcase)\nend","tryCatchPattern":"begin\n  redis.argrep(key, start, stop, match: m, logic: logic)\nrescue ArgumentError\n  retry_allowed = logic = :and  # or surface the allowed values to the caller\n  retry\nend","preventionTips":["Whitelist operator flags from user input against a fixed list","Omit the logic keyword entirely when no combining operator is needed","Name the allowed values in your own error messages when forwarding parameters"],"tags":["argument-validation","enum","arrays"],"backgroundTag":"invalid-option-value","analyzedSha":"2ba9010b91dab9e0fde1fbae3a9aae003f8bc307","analyzedAt":"2026-08-23T03:54:57.017Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}