{"record":{"id":"128fd541410afb46","repo":"ruby/ruby","slug":"not-a-domain-name-other-inspect","errorCode":null,"errorMessage":"not a domain name: #{other.inspect}","messagePattern":"not a domain name: #(.+?)","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"lib/resolv.rb","lineNumber":1354,"sourceCode":"\n      alias eql? == # :nodoc:\n\n      ##\n      # Returns true if +other+ is a subdomain.\n      #\n      # Example:\n      #\n      #   domain = Resolv::DNS::Name.create(\"y.z\")\n      #   p Resolv::DNS::Name.create(\"w.x.y.z\").subdomain_of?(domain) #=> true\n      #   p Resolv::DNS::Name.create(\"x.y.z\").subdomain_of?(domain) #=> true\n      #   p Resolv::DNS::Name.create(\"y.z\").subdomain_of?(domain) #=> false\n      #   p Resolv::DNS::Name.create(\"z\").subdomain_of?(domain) #=> false\n      #   p Resolv::DNS::Name.create(\"x.y.z.\").subdomain_of?(domain) #=> false\n      #   p Resolv::DNS::Name.create(\"w.z\").subdomain_of?(domain) #=> false\n      #\n\n      def subdomain_of?(other)\n        raise ArgumentError, \"not a domain name: #{other.inspect}\" unless Name === other\n        return false if @absolute != other.absolute?\n        other_len = other.length\n        return false if @labels.length <= other_len\n        return @labels[-other_len, other_len] == other.to_a\n      end\n\n      def hash # :nodoc:\n        return @labels.hash ^ @absolute.hash\n      end\n\n      def to_a # :nodoc:\n        return @labels\n      end\n\n      def length # :nodoc:\n        return @labels.length\n      end\n","sourceCodeStart":1336,"sourceCodeEnd":1372,"githubUrl":"https://github.com/ruby/ruby/blob/0e5b888e1c355f3f728f2659f085820937dada48/lib/resolv.rb#L1336-L1372","documentation":"Resolv::DNS::Name#subdomain_of? compares against another Name object and starts by asserting Name === other. Passing a plain String (or anything else) raises ArgumentError, because the method reads other.absolute? and other.to_a, which only exist on Name.","triggerScenarios":"name.subdomain_of?(\"example.com\"); comparing against a host string received from HTTP params, config, or DB before conversion; calling subdomain_of? with a Name built by a different DNS library (e.g. Dnsruby::Name).","commonSituations":"Domain-allowlist checks in request validators; security code testing whether a user-supplied host falls under a corporate domain; mixing string domains and Name objects in the same code path.","solutions":["Convert first: name.subdomain_of?(Resolv::DNS::Name.create(\"example.com\"))","Normalize at the boundary with a helper that coerces strings to Name and passes Name objects through","Mind absolute vs relative names: Name.create(\"example.com\") is relative; use a trailing dot (\"example.com.\") for FQDN semantics, or the answer is false rather than an error"],"exampleFix":"# before\nResolv::DNS::Name.create(req_host).subdomain_of?(\"corp.example.com\")\n# => ArgumentError: not a domain name: \"corp.example.com\"\n\n# after\nzone = Resolv::DNS::Name.create(\"corp.example.com\")\nResolv::DNS::Name.create(req_host).subdomain_of?(zone)","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"def to_dns_name(value)\n  Resolv::DNS::Name === value ? value : Resolv::DNS::Name.create(value)\nend\n\nname.subdomain_of?(to_dns_name(user_host))","tryCatchPattern":null,"preventionTips":["Normalize domains to Resolv::DNS::Name at the input boundary","Decide absolute vs relative explicitly: trailing dot makes Name.create produce absolute names","Never pass raw request strings straight into subdomain_of?"],"tags":["resolv","dns","domain-name","argument-validation","stdlib","ruby"],"backgroundTag":"invalid-argument-type","analyzedSha":"0e5b888e1c355f3f728f2659f085820937dada48","analyzedAt":"2026-08-21T14:25:43.473Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}