{"record":{"id":"8eb1a6c642775626","repo":"ruby/ruby","slug":"library-not-found-for-class-digest-name-l","errorCode":null,"errorMessage":"library not found for class Digest::#{name} -- #{lib}","messagePattern":"library not found for class Digest::#(.+?) -- #(.+?)","errorType":"exception","errorClass":"LoadError","httpStatus":null,"severity":"error","filePath":"ext/digest/lib/digest.rb","lineNumber":33,"sourceCode":"require 'digest/version'\nrequire 'digest/loader'\n\nmodule Digest\n  # A mutex for Digest().\n  REQUIRE_MUTEX = Thread::Mutex.new\n\n  def self.const_missing(name) # :nodoc:\n    case name\n    when :SHA256, :SHA384, :SHA512\n      lib = 'digest/sha2'\n    else\n      lib = File.join('digest', name.to_s.downcase)\n    end\n\n    begin\n      require lib\n    rescue LoadError\n      raise LoadError, \"library not found for class Digest::#{name} -- #{lib}\", caller(1)\n    end\n    unless Digest.const_defined?(name)\n      raise NameError, \"uninitialized constant Digest::#{name}\", caller(1)\n    end\n    Digest.const_get(name)\n  end\n\n  class ::Digest::Class\n    # Creates a digest object and reads a given file, _name_.\n    # Optional arguments are passed to the constructor of the digest\n    # class.\n    #\n    #   p Digest::SHA256.file(\"X11R6.8.2-src.tar.bz2\").hexdigest\n    #   # => \"f02e3c85572dc9ad7cb77c2a638e3be24cc1b5bea9fdbb0b0299c9668475c534\"\n    def self.file(name, *args)\n      new(*args).file(name)\n    end\n","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/ruby/ruby/blob/0e5b888e1c355f3f728f2659f085820937dada48/ext/digest/lib/digest.rb#L15-L51","documentation":"Raised by Gem::Package::Old#extract_files after inflating a file entry: the decompressed byte length does not equal the size recorded in the old-format gem's file-list header. This length cross-check catches truncated or tampered archives — the data decompressed but not to what the index promised. Raised as Gem::Package::FormatError '<file> in <gem> is corrupt'.","triggerScenarios":"Extracting (or `gem install`-ing) an old-format .gem whose payload bytes were altered after packaging, truncated mid-download, or corrupted by a text-mode/encoding-mangling transfer (e.g. FTP in ASCII mode rewriting line endings inside the binary).","commonSituations":"Archived rubyforge gems fetched over flaky HTTP; .gem files transferred through tools that 'helpfully' converted encodings; bit rot on old backups.","solutions":["Re-download the .gem and verify its checksum against the original source","Avoid text-mode transfers: fetch gems with curl -O or the gem CLI, not ASCII-mode FTP","Use a modern re-release of the gem; the old format is unmaintained","Catch Gem::Package::FormatError if batch-processing many old gems and skip bad ones with a report"],"exampleFix":"# before (batch script dies on first corrupt gem)\nGem::Package::Old.new(File.open(path)).extract_files(dir)\n# after\nbegin\n  Gem::Package::Old.new(File.open(path)).extract_files(dir)\nrescue Gem::Package::FormatError => e\n  warn \"skipping corrupt gem #{path}: #{e.message}\"\nend","handlingStrategy":"try-catch","validationCode":"# pre-verify integrity: compare recorded sizes after a manual pass is impractical;\n# instead verify the whole file's SHA-256 against the source before extracting'\nrequire 'digest'\nabort 'checksum mismatch' unless Digest::SHA256.file(path).hexdigest == expected","typeGuard":null,"tryCatchPattern":"begin\n  pkg.extract_files(dest)\nrescue Gem::Package::FormatError => e\n  warn \"corrupt entry, skipping #{path}: #{e.message}\"\nend","preventionTips":["Fetch gems with curl -O / gem CLI over binary-safe HTTP(S)","Verify SHA-256 of archived .gem files against rubygems.org before installing","In batch tooling, rescue FormatError per file and report instead of aborting the run"],"tags":["rubygems","old-format","corruption","checksum","archive"],"backgroundTag":"corrupt-archive","analyzedSha":"0e5b888e1c355f3f728f2659f085820937dada48","analyzedAt":"2026-08-21T14:25:43.473Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}