{"record":{"id":"31f7a609172b67c0","repo":"bblimke/webmock","slug":"the-basic-auth-option-value-should-be-an-array-whi","errorCode":null,"errorMessage":"The basic_auth option value should be an array which contains 2 strings: username and password","messagePattern":"The basic_auth option value should be an array which contains 2 strings: username and password","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"lib/webmock/request_pattern.rb","lineNumber":76,"sourceCode":"      options = WebMock::Util::HashKeysStringifier.stringify_keys!(options, deep: true)\n      HashValidator.new(options).validate_keys('body', 'headers', 'query', 'basic_auth')\n      set_basic_auth_as_headers!(options)\n      @body_pattern = BodyPattern.new(options['body']) if options.has_key?('body')\n      @headers_pattern = HeadersPattern.new(options['headers']) if options.has_key?('headers')\n      @uri_pattern.add_query_params(options['query']) if options.has_key?('query')\n    end\n\n    def set_basic_auth_as_headers!(options)\n      if basic_auth = options.delete('basic_auth')\n        validate_basic_auth!(basic_auth)\n        options['headers'] ||= {}\n        options['headers']['Authorization'] = WebMock::Util::Headers.basic_auth_header(basic_auth[0],basic_auth[1])\n      end\n    end\n\n    def validate_basic_auth!(basic_auth)\n      if !basic_auth.is_a?(Array) || basic_auth.map{|e| e.is_a?(String)}.uniq != [true]\n        raise \"The basic_auth option value should be an array which contains 2 strings: username and password\"\n      end\n    end\n\n    def create_uri_pattern(uri)\n      if uri.is_a?(Regexp)\n        URIRegexpPattern.new(uri)\n      elsif uri.is_a?(Addressable::Template)\n        URIAddressablePattern.new(uri)\n      elsif uri.respond_to?(:call)\n        URICallablePattern.new(uri)\n      elsif uri.is_a?(::URI::Generic)\n        URIStringPattern.new(uri.to_s)\n      elsif uri.respond_to?(:to_str)\n        URIStringPattern.new(uri.to_str)\n      else\n        raise ArgumentError.new(\"URI should be a String, Regexp, Addressable::Template, a callable object, or respond to #to_str. Got: #{uri.class}\")\n      end\n    end","sourceCodeStart":58,"sourceCodeEnd":94,"githubUrl":"https://github.com/bblimke/webmock/blob/b187df8827e1f08a1684a8ddc0a5050dbd449c16/lib/webmock/request_pattern.rb#L58-L94","documentation":"with(basic_auth: ...) expects credentials as an Array of two Strings, e.g. ['user', 'pass']. set_basic_auth_as_headers! deletes the option, validates it, and converts it into an Authorization header via WebMock::Util::Headers.basic_auth_header(basic_auth[0], basic_auth[1]). A non-Array value, or any non-String element (symbols, integers, nil), fails the check basic_auth.map { |e| e.is_a?(String) }.uniq != [true] in lib/webmock/request_pattern.rb:74 and raises this message. Note it is a plain raise, so the exception class is RuntimeError, not ArgumentError.","triggerScenarios":".with(basic_auth: 'user:pass') - a colon-joined string copied from a URL like https://user:pass@example.com. .with(basic_auth: %i[user pass]) - symbols loaded from YAML/config. .with(basic_auth: { username: 'u', password: 'p' }) - hash form. A credentials array where one element is nil because an ENV var is unset, e.g. ['user', ENV['PASS']].","commonSituations":"Copying userinfo credentials out of a URL and pasting them verbatim; config files that symbolize keys and values; shared stub factories that take credentials from settings objects returning symbols or nils.","solutions":["Pass two strings: .with(basic_auth: ['user', 'pass'])","Convert the value you have: 'user:pass'.split(':', 2), or map each element with to_s so every entry is a String","Set the header directly instead of the option: .with(headers: { 'Authorization' => WebMock::Util::Headers.basic_auth_header('user', 'pass') }) - identical to the internal transformation","Guard ENV-based credentials: .with(basic_auth: [ENV['API_USER'].to_s, ENV['API_PASS'].to_s])"],"exampleFix":"# before\nstub_request(:get, 'https://api.example.com/private').with(basic_auth: 'user:pass')  # RuntimeError\n\n# after\nstub_request(:get, 'https://api.example.com/private').with(basic_auth: ['user', 'pass'])","handlingStrategy":"type-guard","validationCode":"creds = 'user:pass'.split(':', 2)\nstub.with(basic_auth: creds) if creds.length == 2 && creds.all? { |c| c.is_a?(String) }","typeGuard":"def valid_basic_auth?(v)\n  v.is_a?(Array) && v.length == 2 && v.all? { |e| e.is_a?(String) }\nend","tryCatchPattern":"begin\n  pattern.with(basic_auth: creds)\nrescue RuntimeError => e\n  raise unless e.message.include?('basic_auth')\n  pattern.with(headers: { 'Authorization' => WebMock::Util::Headers.basic_auth_header(*creds.map(&:to_s)) })\nend","preventionTips":["Never pass userinfo strings whole; split them first","Assert the credentials shape in spec helpers before stubbing","Keep test credentials frozen as ['user', 'pass'] constants"],"tags":["webmock","basic-auth","request-matching","type-validation","ruby"],"backgroundTag":"invalid-argument-type","analyzedSha":"b187df8827e1f08a1684a8ddc0a5050dbd449c16","analyzedAt":"2026-08-23T02:55:22.028Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}