bblimke/webmock · error · RuntimeError
The basic_auth option value should be an array which contain
Error message
The basic_auth option value should be an array which contains 2 strings: username and password
What it means
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.
Source
Thrown at lib/webmock/request_pattern.rb:76
options = WebMock::Util::HashKeysStringifier.stringify_keys!(options, deep: true)
HashValidator.new(options).validate_keys('body', 'headers', 'query', 'basic_auth')
set_basic_auth_as_headers!(options)
@body_pattern = BodyPattern.new(options['body']) if options.has_key?('body')
@headers_pattern = HeadersPattern.new(options['headers']) if options.has_key?('headers')
@uri_pattern.add_query_params(options['query']) if options.has_key?('query')
end
def set_basic_auth_as_headers!(options)
if basic_auth = options.delete('basic_auth')
validate_basic_auth!(basic_auth)
options['headers'] ||= {}
options['headers']['Authorization'] = WebMock::Util::Headers.basic_auth_header(basic_auth[0],basic_auth[1])
end
end
def validate_basic_auth!(basic_auth)
if !basic_auth.is_a?(Array) || basic_auth.map{|e| e.is_a?(String)}.uniq != [true]
raise "The basic_auth option value should be an array which contains 2 strings: username and password"
end
end
def create_uri_pattern(uri)
if uri.is_a?(Regexp)
URIRegexpPattern.new(uri)
elsif uri.is_a?(Addressable::Template)
URIAddressablePattern.new(uri)
elsif uri.respond_to?(:call)
URICallablePattern.new(uri)
elsif uri.is_a?(::URI::Generic)
URIStringPattern.new(uri.to_s)
elsif uri.respond_to?(:to_str)
URIStringPattern.new(uri.to_str)
else
raise ArgumentError.new("URI should be a String, Regexp, Addressable::Template, a callable object, or respond to #to_str. Got: #{uri.class}")
end
endView on GitHub (pinned to b187df8827)
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])
Example fix
# before stub_request(:get, 'https://api.example.com/private').with(basic_auth: 'user:pass') # RuntimeError # after stub_request(:get, 'https://api.example.com/private').with(basic_auth: ['user', 'pass'])
Defensive patterns
Strategy: type-guard
Validate before calling
creds = 'user:pass'.split(':', 2)
stub.with(basic_auth: creds) if creds.length == 2 && creds.all? { |c| c.is_a?(String) } Type guard
def valid_basic_auth?(v)
v.is_a?(Array) && v.length == 2 && v.all? { |e| e.is_a?(String) }
end Try / catch
begin
pattern.with(basic_auth: creds)
rescue RuntimeError => e
raise unless e.message.include?('basic_auth')
pattern.with(headers: { 'Authorization' => WebMock::Util::Headers.basic_auth_header(*creds.map(&:to_s)) })
end Prevention
- 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
When it happens
Trigger: .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']].
Common situations: 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.
Understand the failure class
Background: Invalid argument type errors: "must be of type string", "expected X, got Y", and ERR_INVALID_ARG_TYPE explained — this error's family across 15 libraries.
Related errors
- #with method invoked with no arguments. Either options hash
- URI should be a String, Regexp, Addressable::Template, a cal
- WebMock does not support matching body for multipart/form-da
- must be one of: #{valid_types}. '#{@body.class}' given.
- Real HTTP connections are disabled. Unregistered request: #{
AI-assisted analysis of bblimke/webmock@b187df8827 (2026-08-23).
Data as JSON: /api/errors/31f7a609172b67c0.
Report an issue: GitHub.