{"record":{"id":"64e360827dc745b4","repo":"lostisland/faraday","slug":"unknown-http-method-method","errorCode":null,"errorMessage":"unknown http method: #{method}","messagePattern":"unknown http method: #(.+?)","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"lib/faraday/connection.rb","lineNumber":441,"sourceCode":"        else\n          query_values.to_query(options.params_encoder)\n        end\n\n      uri\n    end\n\n    # Builds and runs the Faraday::Request.\n    #\n    # @param method [Symbol] HTTP method.\n    # @param url [String, URI, nil] String or URI to access.\n    # @param body [String, Hash, Array, nil] The request body that will eventually be converted to\n    #             a string; middlewares can be used to support more complex types.\n    # @param headers [Hash, nil] unencoded HTTP header key/value pairs.\n    #\n    # @return [Faraday::Response]\n    def run_request(method, url, body, headers)\n      unless METHODS.include?(method)\n        raise ArgumentError, \"unknown http method: #{method}\"\n      end\n\n      request = build_request(method) do |req|\n        req.options.proxy = proxy_for_request(url)\n        req.url(url)                if url\n        req.headers.update(headers) if headers\n        req.body = body             if body\n        yield(req) if block_given?\n      end\n\n      builder.build_response(self, request)\n    end\n\n    # Creates and configures the request object.\n    #\n    # @param method [Symbol]\n    #\n    # @yield [Faraday::Request] if block given","sourceCodeStart":423,"sourceCodeEnd":459,"githubUrl":"https://github.com/lostisland/faraday/blob/b25b1b26ccef34b1460b0267115be238ca758087/lib/faraday/connection.rb#L423-L459","documentation":"Connection#run_request validates the HTTP method against Connection::METHODS, a frozen Set of exactly :get, :post, :put, :delete, :head, :patch, :options and :trace. Anything else — strings, upcase or mixed-case symbols, or non-standard verbs — raises ArgumentError before the request is built. This is a deliberate whitelist: Faraday only executes well-known methods, unlike Net::HTTP which accepts arbitrary verbs.","triggerScenarios":"Calling conn.run_request('get', ...) with a String instead of the lowercase Symbol :get; passing :GET or :Get from a copied curl example; data-driven code that reads the method from JSON/YAML config and forwards it unnormalized; requesting CDN or WebDAV verbs such as :purge, :propfind, :mkcol or :copy which are not in the whitelist.","commonSituations":"Purging Fastly/Akamai caches (the :purge verb is the classic case); WebDAV or CalDAV clients; porting Net::HTTP code where arbitrary methods work; config files storing 'POST' as a string; user input choosing the method in an API gateway scenario.","solutions":["Normalize the method before calling run_request: method = method.to_s.downcase.strip.to_sym so 'GET', :Get and 'get ' all become :get.","Whitelist-check the method against your own allow-list and fail with your own error message: Faraday::Connection::METHODS.include?(method).","For genuinely non-standard verbs that the wire protocol still requires, build the request without run_request's validation: req = conn.build_request(:purge) { |r| r.url('/x') }; conn.builder.build_response(conn, req) — build_request performs no METHODS check.","As a last resort, extend the whitelist at boot: Faraday::Connection::METHODS << :purge (METHODS is a mutable Set), then conn.run_request(:purge, ...) passes — document this loudly because built-in adapters may still reject the verb."],"exampleFix":"# before\nmethod = params[:method]        # e.g. \"PURGE\" from config\nconn.run_request(method, '/items', nil, nil)\n# => ArgumentError: unknown http method: PURGE\n\n# after\nmethod = params[:method].downcase.to_sym\nunless Faraday::Connection::METHODS.include?(method)\n  raise ArgumentError, \"unsupported method #{method}\"\nend\nconn.run_request(method, '/items', nil, nil)","handlingStrategy":"validation","validationCode":"method = method.to_s.downcase.to_sym\nraise ArgumentError, \"unsupported method #{method}\" unless Faraday::Connection::METHODS.include?(method)\nconn.run_request(method, url, body, headers)","typeGuard":"def supported_http_method?(method)\n  Faraday::Connection::METHODS.include?(method.to_s.downcase.to_sym)\nend","tryCatchPattern":"begin\n  conn.run_request(method, url, body, headers)\nrescue ArgumentError => e\n  raise unless e.message.start_with?('unknown http method')\n  # normalize casing/strings and retry once\n  conn.run_request(method.to_s.downcase.to_sym, url, body, headers)\nend","preventionTips":["Whitelist methods at your API boundary instead of forwarding raw user input to run_request.","Store HTTP methods in config as lowercase symbols (:post, not 'POST') and normalize defensively with to_s.downcase.to_sym.","For custom verbs, prefer build_request + builder.build_response which bypass the METHODS check, over monkey-patching the whitelist."],"tags":["ruby","faraday","http-method","argumenterror","whitelist","webdav"],"backgroundTag":"unsupported-http-method","analyzedSha":"b25b1b26ccef34b1460b0267115be238ca758087","analyzedAt":"2026-08-21T19:43:20.220Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}