{"record":{"id":"0a3724183e25ced8","repo":"jdx/mise","slug":"context-missing-sha256","errorCode":null,"errorMessage":"#{context}: missing sha256","messagePattern":"#(.+?): missing sha256","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"src/system/packages/brew/shim.rb","lineNumber":72,"sourceCode":"\ndef odie(message)\n  $stderr.puts \"Error: #{message}\"\n  exit 1\nend\n\nclass ShimUnsupportedError < StandardError; end\n\ndef shim_unsupported!(feature)\n  raise ShimUnsupportedError,\n        \"formula uses `#{feature}`, which mise's source-build shim does not support\"\nend\n\nmodule MiseDownload\n  module_function\n\n  # download with redirects into the cache, verify, return the path\n  def fetch(url, sha256, context)\n    raise \"#{context}: missing sha256\" if sha256.to_s.strip.empty?\n    sha256 = sha256.to_s.strip.downcase\n    raise \"#{context}: malformed sha256\" unless sha256.match?(/\\A[0-9a-f]{64}\\z/)\n\n    MISE_BREW_CACHE.mkpath\n    dest = MISE_BREW_CACHE + \"#{sha256}--#{File.basename(URI(url).path)}\"\n    unless dest.file? && Digest::SHA256.file(dest).hexdigest == sha256\n      ohai \"Downloading #{url}\"\n      tmp = Pathname.new(\"#{dest}.incomplete\")\n      URI.open(url, \"rb\", redirect: true) do |remote|\n        tmp.open(\"wb\") { |f| IO.copy_stream(remote, f) }\n      end\n      actual = Digest::SHA256.file(tmp).hexdigest\n      if actual != sha256\n        tmp.unlink\n        raise \"#{context}: sha256 mismatch (expected #{sha256}, got #{actual})\"\n      end\n      tmp.rename(dest)\n    end","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/system/packages/brew/shim.rb#L54-L90","documentation":"A Ruby raise in the brew shim's fetch: a download was requested without a sha256 checksum. The shim intentionally refuses to fetch (and later verify) artifacts without an explicit checksum, since it enforces supply-chain integrity for compiler toolchain downloads.","triggerScenarios":"Calling fetch (directly or via cc/cxx) with sha256 nil or an empty/whitespace string — e.g. a package definition that omits the sha256 field for a source URL.","commonSituations":"Hand-written or generated package specs missing checksums; formulas migrated from sources without recorded digests; environment/tooling that strips optional fields.","solutions":["Add the correct sha256 for the source URL to the package definition","Compute it with `shasum -a 256 <archive>` or `curl -sL <url> | shasum -a 256` and paste the digest","If the source is genuinely unofficial/ephemeral, vendor a pinned artifact with a known digest","Check for whitespace-only values that fail the strip.empty? guard"],"exampleFix":"# before\nMiseDownload.fetch(url, nil, \"llvm\")\n# after\nMiseDownload.fetch(url, \"e2b1a4...64hex...\", \"llvm\")","handlingStrategy":"validation","validationCode":"raise \"missing sha256 for #{context}\" if sha256.nil? || sha256.to_s.strip.empty?","typeGuard":"def valid_sha256?(s)\n  s.is_a?(String) && s.match?(/\\A[0-9a-fA-F]{64}\\z/)\nend","tryCatchPattern":"begin\n  path = MiseDownload.fetch(url, sha256, context)\nrescue RuntimeError => e\n  warn \"skipping #{context}: #{e.message}\"\nend","preventionTips":["Always pin a sha256 for every downloaded artifact","Generate digests with `shasum -a 256`, never md5","Validate package definitions in CI before publishing"],"tags":["ruby","checksum","validation","brew-shim"],"backgroundTag":"checksum-mismatch","analyzedSha":"533346cc374382b41ec5ff70536252b2e96e725c","analyzedAt":"2026-09-17T13:35:38.149Z","contentChangedAt":"2026-09-17T13:35:38.149Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}