jnunemaker/httparty · error · ArgumentError

Default params must be an object which responds to #to_hash

Error message

Default params must be an object which responds to #to_hash

What it means

The class-level DSL method `default_params` raises ArgumentError unless its argument responds to #to_hash. default_params is meant to merge a Hash of query parameters (like API keys) that HTTParty appends to every request; anything that is not Hash-like (or an object converted via to_hash) is rejected immediately at class-definition time rather than producing a broken query string later.

Source

Thrown at lib/httparty.rb:172

    #
    # @example
    #   class Foo
    #     include HTTParty
    #     disable_rails_query_string_format
    #   end
    def disable_rails_query_string_format
      query_string_normalizer Request::NON_RAILS_QUERY_STRING_NORMALIZER
    end

    # Allows setting default parameters to be appended to each request.
    # Great for api keys and such.
    #
    #   class Foo
    #     include HTTParty
    #     default_params api_key: 'secret', another: 'foo'
    #   end
    def default_params(h = {})
      raise ArgumentError, 'Default params must be an object which responds to #to_hash' unless h.respond_to?(:to_hash)
      default_options[:default_params] ||= {}
      default_options[:default_params].merge!(h)
    end

    # Allows setting a default timeout for all HTTP calls
    # Timeout is specified in seconds.
    #
    #   class Foo
    #     include HTTParty
    #     default_timeout 10
    #   end
    def default_timeout(value)
      validate_timeout_argument(__method__, value)
      default_options[:timeout] = value
    end

    # Allows setting a default open_timeout for all HTTP calls in seconds
    #

View on GitHub (pinned to 8f4a09e343)

Solutions

  1. Pass a plain Hash: `default_params api_key: 'secret'`.
  2. Convert external input before the call: `default_params JSON.parse(raw)` or `default_params raw.to_h`.
  3. Guard dynamic values: `default_params params if params.respond_to?(:to_hash)`.

Example fix

# before
default_params ENV['DEFAULT_PARAMS']        # String -> ArgumentError

# after
require 'json'
default_params JSON.parse(ENV['DEFAULT_PARAMS'] || '{}')
Defensive patterns

Strategy: validation

Validate before calling

raise ArgumentError, 'default_params must be a Hash' unless params.respond_to?(:to_hash)
default_params params.to_hash

Type guard

hash_like = ->(v) { v.respond_to?(:to_hash) }

Try / catch

begin
  default_params parsed
rescue ArgumentError => e
  raise ConfigError, "bad default_params config: #{e.message}"
end

Prevention

When it happens

Trigger: Calling `default_params 'foo'`, `default_params nil`, `default_params [[:key, 'v']]`, or `default_params ENV['API_PARAMS']` (a String) inside a class that includes HTTParty. Also triggered by passing a JSON-encoded string instead of a parsed Hash.

Common situations: Loading params from YAML/ENV/JSON files that yield Strings or nil, porting code from libraries that accept arrays of pairs, and typos like `default_params :api_key => 'k'` where the hash is accidentally wrapped or omitted.

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


AI-assisted analysis of jnunemaker/httparty@8f4a09e343 (2026-08-21). Data as JSON: /api/errors/42705fe600a6f39d. Report an issue: GitHub.