{"record":{"id":"ce85d26108b3e273","repo":"jnunemaker/httparty","slug":"only-get-post-patch-put-delete-head-and-opti","errorCode":null,"errorMessage":"only get, post, patch, put, delete, head, and options methods are supported","messagePattern":"only get, post, patch, put, delete, head, and options methods are supported","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"lib/httparty/request.rb","lineNumber":416,"sourceCode":"      cookies_hash.add_cookies(options[:headers].to_hash['Cookie']) if options[:headers] && options[:headers].to_hash['Cookie']\n      response.get_fields('Set-Cookie').each { |cookie| cookies_hash.add_cookies(cookie) }\n\n      options[:headers] ||= {}\n      options[:headers]['Cookie'] = cookies_hash.to_cookie_string\n    end\n\n    # Uses the HTTP Content-Type header to determine the format of the\n    # response It compares the MIME type returned to the types stored in the\n    # SupportedFormats hash\n    def format_from_mimetype(mimetype)\n      if mimetype && parser.respond_to?(:format_from_mimetype)\n        parser.format_from_mimetype(mimetype)\n      end\n    end\n\n    def validate\n      raise HTTParty::RedirectionTooDeep.new(last_response), 'HTTP redirects too deep' if options[:limit].to_i <= 0\n      raise ArgumentError, 'only get, post, patch, put, delete, head, and options methods are supported' unless SupportedHTTPMethods.include?(http_method)\n      raise ArgumentError, ':headers must be a hash' if options[:headers] && !options[:headers].respond_to?(:to_hash)\n      raise ArgumentError, 'only one authentication method, :basic_auth or :digest_auth may be used at a time' if options[:basic_auth] && options[:digest_auth]\n      raise ArgumentError, ':basic_auth must be a hash' if options[:basic_auth] && !options[:basic_auth].respond_to?(:to_hash)\n      raise ArgumentError, ':digest_auth must be a hash' if options[:digest_auth] && !options[:digest_auth].respond_to?(:to_hash)\n      raise ArgumentError, ':query must be hash if using HTTP Post' if post? && !options[:query].nil? && !options[:query].respond_to?(:to_hash)\n    end\n\n    def post?\n      Net::HTTP::Post == http_method\n    end\n\n    def set_basic_auth_from_uri\n      if path.userinfo\n        username, password = path.userinfo.split(':')\n        options[:basic_auth] = {username: username, password: password}\n        @credentials_sent = true\n      end\n    end","sourceCodeStart":398,"sourceCodeEnd":434,"githubUrl":"https://github.com/jnunemaker/httparty/blob/8f4a09e343b94de9f934f388028ca97620c9b378/lib/httparty/request.rb#L398-L434","documentation":"Request#validate raises ArgumentError 'only get, post, patch, put, delete, head, and options methods are supported' unless http_method is in SupportedHTTPMethods (the Net::HTTP classes Get, Post, Patch, Put, Delete, Head, Options). The public DSL only exposes those verbs, so this fires when a Request is constructed manually or via perform_request with another Net::HTTP class such as Net::HTTP::Trace or Net::HTTP::Connect. Note validate also checks the redirect limit first, so a exhausted limit raises RedirectionTooDeep instead.","triggerScenarios":"`HTTParty::Request.new(Net::HTTP::Trace, 'http://x/').perform`, calling `YourClient.perform_request(Net::HTTP::Propfind, path, {})`, or library code that maps arbitrary symbols to Net::HTTP verb classes and passes one through to httparty.","commonSituations":"Needing TRACE/CONNECT/PROPFIND or custom verbs for WebDAV/debug endpoints, wrapping httparty behind a generic `request(method, url)` facade, and copying Net::HTTP examples into httparty code.","solutions":["Restrict the facade to the supported verbs (get, post, patch, put, delete, head, options).","For unsupported verbs, drop to Net::HTTP directly for those calls.","If you truly need custom verbs through httparty, verify `HTTParty::Request::SupportedHTTPMethods.include?(klass)` before dispatch and branch accordingly."],"exampleFix":"# before\ndef request(method, url)\n  klass = Net::HTTP.const_get(method.to_s.capitalize)\n  self.class.perform_request(klass, url, {})   # Trace -> ArgumentError\nend\n\n# after\nSUPPORTED = %i[get post patch put delete head options].freeze\ndef request(method, url)\n  raise ArgumentError, \"unsupported verb #{method}\" unless SUPPORTED.include?(method.to_sym)\n  public_send(method, url)\nend","handlingStrategy":"validation","validationCode":"klass = Net::HTTP.const_get(method.to_s.capitalize)\nraise ArgumentError, \"unsupported method #{method}\" unless HTTParty::Request::SupportedHTTPMethods.include?(klass)\nperform_request(klass, path, options)","typeGuard":"supported_verb = ->(m) { %i[get post patch put delete head options].include?(m.to_sym) }","tryCatchPattern":"begin\n  perform_request(klass, path, options)\nrescue ArgumentError => e\n  raise unless e.message.include?('methods are supported')\n  raise NotImplementedError, \"#{klass} not supported by httparty; use Net::HTTP directly\"\nend","preventionTips":["Whitelist verbs at your wrapper's boundary.","Route WebDAV/TRACE-style calls to Net::HTTP from the start.","Remember httparty's supported set is fixed per version; check SupportedHTTPMethods when upgrading."],"tags":["ruby","httparty","validation","argument-error","http-method","verb"],"backgroundTag":"unsupported-http-method","analyzedSha":"8f4a09e343b94de9f934f388028ca97620c9b378","analyzedAt":"2026-08-21T19:30:42.003Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}