{"record":{"id":"1997da2f770ab9fb","repo":"jnunemaker/httparty","slug":"only-one-authentication-method-basic-auth-or-di","errorCode":null,"errorMessage":"only one authentication method, :basic_auth or :digest_auth may be used at a time","messagePattern":"only one authentication method, :basic_auth or :digest_auth may be used at a time","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"lib/httparty/request.rb","lineNumber":418,"sourceCode":"\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\n\n    def decompress(body, encoding)","sourceCodeStart":400,"sourceCodeEnd":436,"githubUrl":"https://github.com/jnunemaker/httparty/blob/8f4a09e343b94de9f934f388028ca97620c9b378/lib/httparty/request.rb#L400-L436","documentation":"Request#validate raises ArgumentError when both options[:basic_auth] and options[:digest_auth] are present on the same request. HTTParty cannot apply two WWW-Authenticate schemes at once and refuses to risk sending credentials computed for the wrong challenge. The conflict can come from a single call or from class-level defaults merging with per-request options.","triggerScenarios":"`Foo.get(url, basic_auth: { username: u, password: p }, digest_auth: { username: u, password: p })`; class-level `basic_auth u, p` combined with a per-request `digest_auth:` option (defaults are deep-merged into request options); credentials extracted from a URI userinfo combined with an explicit digest_auth hash.","commonSituations":"Switching an API from Basic to Digest auth and leaving the old setting behind, shared client base classes setting basic_auth for all children while one endpoint needs digest, and copying both options from a provider's docs 'to be safe'.","solutions":["Use exactly one auth type per request: remove the other key.","If a base class sets basic_auth, override per-request with `basic_auth: nil`... instead restructure: clear defaults or use separate client classes.","For endpoints with different schemes, split into two HTTParty classes (one basic, one digest)."],"exampleFix":"# before\nclass Base\n  include HTTParty\n  basic_auth 'u', 'p'\nend\nBase.get(url, digest_auth: { username: 'u', password: 'p' })  # ArgumentError\n\n# after\nclass BasicClient\n  include HTTParty\n  basic_auth 'u', 'p'\nend\nclass DigestClient\n  include HTTParty\n  digest_auth 'u', 'p'\nend","handlingStrategy":"validation","validationCode":"raise ArgumentError, 'use only one of basic_auth/digest_auth' if opts.key?(:basic_auth) && opts.key?(:digest_auth)\nFoo.get(url, **opts)","typeGuard":null,"tryCatchPattern":"begin\n  Foo.get(url, **opts)\nrescue ArgumentError => e\n  raise unless e.message.include?('authentication method')\n  opts = opts.except(:basic_auth)  # or :digest_auth, per target API\n  retry\nend","preventionTips":["One client class per authentication scheme.","Audit class-level defaults before adding per-request auth options.","When switching an API from Basic to Digest, grep the codebase for the old option."],"tags":["ruby","httparty","validation","argument-error","authentication","basic-auth","digest-auth"],"backgroundTag":"conflicting-auth-configuration","analyzedSha":"8f4a09e343b94de9f934f388028ca97620c9b378","analyzedAt":"2026-08-21T19:30:42.003Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}