{"record":{"id":"59d610b5a549ec7b","repo":"bblimke/webmock","slug":"unknown-key-k-inspect-valid-keys-are-valid","errorCode":null,"errorMessage":"Unknown key: #{k.inspect}. Valid keys are: #{valid_keys.map(&:inspect).join(', ')}","messagePattern":"Unknown key: #(.+?)\\. Valid keys are: #(.+?)","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"lib/webmock/util/hash_validator.rb","lineNumber":14,"sourceCode":"# frozen_string_literal: true\n\nmodule WebMock\n  class HashValidator\n    def initialize(hash)\n      @hash = hash\n    end\n\n    #This code is based on https://github.com/rails/rails/blob/master/activesupport/lib/active_support/core_ext/hash/keys.rb\n    def validate_keys(*valid_keys)\n      valid_keys.flatten!\n      @hash.each_key do |k|\n        unless valid_keys.include?(k)\n          raise ArgumentError.new(\"Unknown key: #{k.inspect}. Valid keys are: #{valid_keys.map(&:inspect).join(', ')}\")\n        end\n      end\n    end\n  end\nend\n","sourceCodeStart":1,"sourceCodeEnd":20,"githubUrl":"https://github.com/bblimke/webmock/blob/b187df8827e1f08a1684a8ddc0a5050dbd449c16/lib/webmock/util/hash_validator.rb#L1-L20","documentation":"WebMock validates the options hash passed to stub_request(...).with(...) (and to WebMock::RequestPattern.new) against a fixed whitelist: body, headers, query and basic_auth (lib/webmock/request_pattern.rb:59). Any other key raises ArgumentError, and the message itself enumerates the accepted keys. The guard exists to catch misspelled or unsupported matching options early, before a stub silently matches nothing.","triggerScenarios":"Calling .with() with a typo'd or unsupported key: .with(header: {...}) instead of headers:, .with(params: {...}) instead of query:, .with(json_body: ...) instead of body:, .with(auth: [...]) instead of basic_auth:. Also hit when building WebMock::RequestPattern.new(method, uri, options) directly with extra keys, or when a helper merges unrelated keys (e.g. :timeout) into the .with hash.","commonSituations":"Typos in the four option names; porting stubs from other libraries (FakeWeb/VCR style params or json options); assuming WebMock supports arbitrary matcher keys like :json or :timeout; programmatic option building where an unrelated key slips into the hash; examples copied from outdated blog posts.","solutions":["Read the message - it enumerates the only valid keys: body, headers, query, basic_auth","Rename the misspelled key (header -> headers, params -> query, auth -> basic_auth, json_body -> body)","Pass JSON payloads under body: as a Hash or JSON string, not json: or json_body:","For matching WebMock does not support, use the block form: .with { |req| req.headers['X-Token'] == 'abc' }"],"exampleFix":"// before\nstub_request(:get, 'www.example.com').with(header: { 'Accept' => 'application/json' })\n# => ArgumentError: Unknown key: header (valid: body, headers, query, basic_auth)\n\n// after\nstub_request(:get, 'www.example.com').with(headers: { 'Accept' => 'application/json' })","handlingStrategy":"validation","validationCode":"VALID_WITH_KEYS = %w[body headers query basic_auth].freeze\n\noptions = { headers: { 'Accept' => 'application/json' } }\nunknown = options.keys.map(&:to_s) - VALID_WITH_KEYS\nraise ArgumentError, \"unsupported .with keys: #{unknown.join(', ')}\" if unknown.any?\n\nstub_request(:get, 'www.example.com').with(options)","typeGuard":"def valid_webmock_with_options?(opts)\n  opts.is_a?(Hash) && (opts.keys.map(&:to_s) - %w[body headers query basic_auth]).empty?\nend","tryCatchPattern":"begin\n  stub_request(:get, 'www.example.com').with(options)\nrescue ArgumentError => e\n  # e.message enumerates every valid key - re-raise with a hint pointing at typos\n  raise ArgumentError, \"bad .with options (#{e.message}) - check header vs headers, params vs query\"\nend","preventionTips":["Memorize the four .with keys: body, headers, query, basic_auth","Use the block form .with { |req| ... } for any matching not covered by the four keys","Centralize stub option building in one helper so a typo fails in exactly one place"],"tags":["webmock","ruby","argumenterror","stub-options","typo"],"backgroundTag":"unknown-option-key","analyzedSha":"b187df8827e1f08a1684a8ddc0a5050dbd449c16","analyzedAt":"2026-08-23T02:55:22.028Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}