{"record":{"id":"960afb469b4e6662","repo":"bblimke/webmock","slug":"key-was-repeated-key-inspect","errorCode":null,"errorMessage":"Key was repeated: #{key.inspect}","messagePattern":"Key was repeated: #(.+?)","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"lib/webmock/util/query_mapper.rb","lineNumber":97,"sourceCode":"      end\n\n      def collect_query_hash(query_array, empty_accumulator, options)\n        query_array.compact.inject(empty_accumulator.dup) do |accumulator, (key, value)|\n          value = if value.nil?\n                    nil\n                  else\n                    ::Addressable::URI.unencode_component(value.tr('+', ' '))\n                  end\n          key = Addressable::URI.unencode_component(key)\n          key = key.dup.force_encoding(Encoding::ASCII_8BIT) if key.respond_to?(:force_encoding)\n          self.__send__(\"fill_accumulator_for_#{options[:notation]}\", accumulator, key, value)\n          accumulator\n        end\n      end\n\n      def fill_accumulator_for_flat(accumulator, key, value)\n        if accumulator[key]\n          raise ArgumentError, \"Key was repeated: #{key.inspect}\"\n        end\n        accumulator[key] = value\n      end\n\n      def fill_accumulator_for_flat_array(accumulator, key, value)\n        accumulator << [key, value]\n      end\n\n      def fill_accumulator_for_dot(accumulator, key, value)\n        array_value = false\n        subkeys = key.split(\".\")\n        current_hash = accumulator\n        subkeys[0..-2].each do |subkey|\n          current_hash[subkey] = {} unless current_hash[subkey]\n          current_hash = current_hash[subkey]\n        end\n        if array_value\n          if current_hash[subkeys.last] && !current_hash[subkeys.last].is_a?(Array)","sourceCodeStart":79,"sourceCodeEnd":115,"githubUrl":"https://github.com/bblimke/webmock/blob/b187df8827e1f08a1684a8ddc0a5050dbd449c16/lib/webmock/util/query_mapper.rb#L79-L115","documentation":"With notation :flat, QueryMapper maps each query-string key to a single scalar value; a repeated key (a=1&a=2) cannot be represented in that shape, so fill_accumulator_for_flat raises ArgumentError naming the duplicated key. The query string itself is legal - this is a data-shape conflict between the input and the chosen notation, not a parse failure.","triggerScenarios":"WebMock::Util::QueryMapper.query_to_values('q=1&q=2', notation: :flat); URLs with repeated parameters (tag=ruby&tag=testing, duplicated utm_source) processed through :flat during URL normalization or by custom code built on QueryMapper.","commonSituations":"APIs that encode arrays as repeated bare keys (ids=1&ids=2) instead of bracket syntax; analytics/marketing URLs with duplicated utm parameters; switching from :subscript (the default) to :flat without checking the data; normalizing third-party URLs you do not control.","solutions":["Use notation :flat_array - it keeps duplicates as [key, value] pairs","Use :subscript (the default), which folds repeated keys into an Array under one key","De-duplicate the query string upstream when the repeated keys are unintended"],"exampleFix":"// before\nvalues = WebMock::Util::QueryMapper.query_to_values('tag=ruby&tag=testing', notation: :flat)\n# => ArgumentError: Key was repeated: tag\n\n// after\nvalues = WebMock::Util::QueryMapper.query_to_values('tag=ruby&tag=testing', notation: :flat_array)\n# => [['tag', 'ruby'], ['tag', 'testing']]","handlingStrategy":"validation","validationCode":"def repeated_query_keys?(query)\n  keys = query.to_s.split('&').map { |pair| pair.split('=').first }\n  keys.size != keys.uniq.size\nend\n\nquery = 'tag=ruby&tag=testing'\nnotation = repeated_query_keys?(query) ? :flat_array : :flat\nvalues = WebMock::Util::QueryMapper.query_to_values(query, notation: notation)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Default to :subscript or :flat_array; reserve :flat for queries you know have unique keys","Check for duplicate keys before flattening third-party URLs","When you control the client, encode arrays with bracket syntax (a[]=1) instead of repeated bare keys"],"tags":["webmock","ruby","query-string","duplicate-keys","argumenterror"],"backgroundTag":"duplicate-query-parameter","analyzedSha":"b187df8827e1f08a1684a8ddc0a5050dbd449c16","analyzedAt":"2026-08-23T02:55:22.028Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}