{"record":{"id":"a6b24f20e33776f3","repo":"lostisland/faraday","slug":"can-t-convert-params-class-into-hash-a6b24f","errorCode":null,"errorMessage":"Can't convert #{params.class} into Hash.","messagePattern":"Can't convert #(.+?) into Hash\\.","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"lib/faraday/encoders/nested_params_encoder.rb","lineNumber":16,"sourceCode":"# frozen_string_literal: true\n\nmodule Faraday\n  # Sub-module for encoding parameters into query-string.\n  module EncodeMethods\n    # @param params [nil, Array, #to_hash] parameters to be encoded\n    #\n    # @return [String] the encoded params\n    #\n    # @raise [TypeError] if params can not be converted to a Hash\n    def encode(params)\n      return nil if params.nil?\n\n      unless params.is_a?(Array)\n        unless params.respond_to?(:to_hash)\n          raise TypeError, \"Can't convert #{params.class} into Hash.\"\n        end\n\n        params = params.to_hash\n        params = params.map do |key, value|\n          key = key.to_s if key.is_a?(Symbol)\n          [key, value]\n        end\n\n        # Only to be used for non-Array inputs. Arrays should preserve order.\n        params.sort! if @sort_params\n      end\n\n      # The params have form [['key1', 'value1'], ['key2', 'value2']].\n      buffer = +''\n      params.each do |parent, value|\n        encoded_parent = escape(parent)\n        buffer << \"#{encode_pair(encoded_parent, value)}&\"\n      end","sourceCodeStart":1,"sourceCodeEnd":34,"githubUrl":"https://github.com/lostisland/faraday/blob/b25b1b26ccef34b1460b0267115be238ca758087/lib/faraday/encoders/nested_params_encoder.rb#L1-L34","documentation":"Faraday::NestedParamsEncoder.encode serializes params into Rails-style nested query strings (a[b]=c). Like the flat encoder it accepts nil, an Array of pairs, or anything responding to #to_hash, and raises TypeError for all other inputs. The nested encoder is Faraday's default for encoding, so this error surfaces on ordinary conn.get(url, params) calls with a bad params object.","triggerScenarios":"Passing a pre-encoded query String as params: conn.post('/items', 'a=1&b=2') — the second positional argument of post is the body, but with get it is params, and both reach an encoder; passing an Integer, Symbol or custom object that has no #to_hash; feeding a JSON payload string into params by mistake.","commonSituations":"Confusing the argument order of conn.get(url, params) with conn.post(url, body); assuming params accepts a query string like URI.encode_www_form output; migrating from other HTTP clients whose param arguments are strings; sending a StringIO or IO-like object as params.","solutions":["Pass a Hash of params: conn.get('/search', q: 'ruby', filters: { lang: 'en' }) — nesting is what this encoder is for.","If the query string is already built, append it to the URL: conn.get(\"/search?#{qs}\") and pass no params argument.","For Array inputs, give [key, value] pairs: conn.get(url, [[:a, 1], [:b, 2]]) — Arrays skip sorting to preserve order.","Convert exotic objects on the caller side with .to_h, or implement #to_hash on the class."],"exampleFix":"# before\nconn.get('/search', 'q=ruby&lang=en')\n# => TypeError: Can't convert String into Hash.\n\n# after\nconn.get('/search', q: 'ruby', lang: 'en')\n# equivalent nested form:\nconn.get('/search', q: 'ruby', filters: { lang: 'en' }) # /search?q=ruby&filters[lang]=en","handlingStrategy":"type-guard","validationCode":"raise TypeError, 'params must be a Hash' unless params.is_a?(Hash)\nconn.get(url, params)","typeGuard":"def encodable_params?(params)\n  params.nil? || params.is_a?(Array) || params.respond_to?(:to_hash)\nend","tryCatchPattern":"begin\n  conn.get(url, params)\nrescue TypeError => e\n  raise unless e.message.include?('into Hash')\n  conn.get(\"#{url}?#{URI.encode_www_form(params)}\") if params.is_a?(String)\nend","preventionTips":["Remember the nested encoder is the default: conn.get(url, params) encodes params, it does not append a raw string.","Keep argument orders straight — get(url, params) vs post(url, body) — review when porting between HTTP clients.","For objects without #to_hash, convert with .to_h at the call site before passing."],"tags":["ruby","faraday","params","nested-params","query-string","typeerror"],"backgroundTag":"invalid-query-params","analyzedSha":"b25b1b26ccef34b1460b0267115be238ca758087","analyzedAt":"2026-08-21T19:43:20.220Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}