{"record":{"id":"ef7833ab53c1ced6","repo":"redis/redis-rb","slug":"wrong-number-of-arguments-expected-key-path-value","errorCode":null,"errorMessage":"wrong number of arguments (expected key/path/value triplets)","messagePattern":"wrong number of arguments \\(expected key/path/value triplets\\)","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"lib/redis/commands/modules/json.rb","lineNumber":162,"sourceCode":"      end\n\n      # Set one or more JSON values atomically, one per +key+/+path+/+value+ triplet. Either all\n      # of the writes are applied or none are. For a key that does not yet exist the +path+ must\n      # be the root (\"$\").\n      #\n      # By default each value is a Ruby object serialized with JSON.generate; pass +raw: true+ to\n      # send already-encoded JSON strings through untouched.\n      #\n      # @example\n      #   redis.json_mset(\"doc1\", \"$\", { \"a\" => 1 }, \"doc2\", \"$\", { \"b\" => 2 })\n      #     # => \"OK\"\n      #\n      # @param [Array] args a flat list of key, path, value triplets\n      # @param [Boolean] raw treat each value as an already-encoded JSON string\n      # @return [String] the raw \"OK\" reply\n      # @raise [ArgumentError] unless +args+ is a non-empty list of complete triplets\n      def json_mset(*args, raw: false)\n        raise ArgumentError, \"wrong number of arguments (expected key/path/value triplets)\" \\\n          if args.empty? || !(args.size % 3).zero?\n\n        command = [:\"JSON.MSET\"]\n        args.each_slice(3) do |key, path, value|\n          command << key << path << (raw ? value : ::JSON.generate(value))\n        end\n        send_command(command)\n      end\n\n      # Get the values at a single +path+ from one or more +keys+.\n      #\n      # Returns one element per key, in order, parsed from JSON text into a Ruby object (or nil\n      # when the key or path does not exist). Pass +raw: true+ to get the unparsed JSON strings.\n      #\n      # @example\n      #   redis.json_mget(\"doc1\", \"doc2\", \"$.a\")\n      #     # => [[1], [2]]\n      #","sourceCodeStart":144,"sourceCodeEnd":180,"githubUrl":"https://github.com/redis/redis-rb/blob/2ba9010b91dab9e0fde1fbae3a9aae003f8bc307/lib/redis/commands/modules/json.rb#L144-L180","documentation":"JSON.MSET writes several key/path/value triplets in one atomic command, and the Ruby wrapper takes them as a flat splat, so the total argument count must be a positive multiple of 3. An empty call, or a trailing partial triplet, raises ArgumentError before any serialization happens (lib/redis/commands/modules/json.rb:162). Note that redis.json_mset(some_array) passes ONE argument (an Array), which is not divisible by 3 and hits the same raise.","triggerScenarios":"redis.json_mset() with no args; redis.json_mset(\"doc\", \"$\") with only 2 args; a dynamically built list of 7 elements whose last triplet lost its value; redis.json_mset(triplets) where triplets is an Array that was never splatted.","commonSituations":"Forgetting the splat when the triplets live in an array; looping with each_slice(3) over an odd-length list and pushing a partial tail; refactoring several json_set calls into one batched mset and miscounting arguments.","solutions":["Splat the list: redis.json_mset(*triplets)","Validate !triplets.empty? && triplets.size % 3 == 0 before calling","When building triplets in a loop, append key, path and value together so a partial triplet cannot be produced"],"exampleFix":"// before\nredis.json_mset(triplets)\n// after\nredis.json_mset(*triplets)","handlingStrategy":"validation","validationCode":"def json_mset_bulk(redis, *triplets)\n  raise ArgumentError, \"expected key/path/value triplets\" if triplets.empty? || triplets.size % 3 != 0\n  redis.json_mset(*triplets)\nend","typeGuard":"triplets.is_a?(Array) && !triplets.empty? && (triplets.size % 3).zero?","tryCatchPattern":"begin\n  redis.json_mset(*triplets)\nrescue ArgumentError => e\n  raise BatchError, \"triplet list malformed: #{e.message}\"\nend","preventionTips":["Splat arrays into json_mset, never pass the array itself","Keep triplets as [key, path, value] rows so the structure is checkable before flattening","Unit-test the triplet builder with odd-length inputs"],"tags":["redis-json","json-mset","argumenterror","arity","splat"],"backgroundTag":"wrong-number-of-arguments","analyzedSha":"2ba9010b91dab9e0fde1fbae3a9aae003f8bc307","analyzedAt":"2026-08-23T03:54:57.017Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}