jdx/mise · error · ShimUnsupportedError
formula uses `#{feature}`, which mise's source-build shim do
Error message
formula uses `#{feature}`, which mise's source-build shim does not support What it means
mise can source-build Homebrew formulae without Homebrew by evaluating the formula's .rb in its own Formula-DSL shim (shim.rb, invoked from src/system/packages/brew/source.rs). It implements 'the commonly-used subset of the Formula DSL; formulae that reach outside it fail loudly with a clear message rather than miscompiling silently' (file header). When a formula's install code uses something outside that subset, `shim_unsupported!` raises ShimUnsupportedError with `formula uses \`X\`, which mise's source-build shim does not support`. Concrete raisers in shim.rb: resource patches (line 405), resources declaring a non-nil download strategy `using:` (line 410), unknown `on_system :macos =>` condition symbols (line 614), inline `patch` strings via `:DATA`-style sources (line 659), `testpath` (line 718), and any unknown install-time helper method called inside `def install` (line 858).
Source
Thrown at src/system/packages/brew/shim.rb:63
def ohai(*args)
$stdout.puts "==> #{args.join(" ")}"
$stdout.flush
end
def opoo(message)
$stderr.puts "Warning: #{message}"
end
def odie(message)
$stderr.puts "Error: #{message}"
exit 1
end
class ShimUnsupportedError < StandardError; end
def shim_unsupported!(feature)
raise ShimUnsupportedError,
"formula uses `#{feature}`, which mise's source-build shim does not support"
end
module MiseDownload
module_function
# download with redirects into the cache, verify, return the path
def fetch(url, sha256, context)
raise "#{context}: missing sha256" if sha256.to_s.strip.empty?
sha256 = sha256.to_s.strip.downcase
raise "#{context}: malformed sha256" unless sha256.match?(/\A[0-9a-f]{64}\z/)
MISE_BREW_CACHE.mkpath
dest = MISE_BREW_CACHE + "#{sha256}--#{File.basename(URI(url).path)}"
unless dest.file? && Digest::SHA256.file(dest).hexdigest == sha256
ohai "Downloading #{url}"
tmp = Pathname.new("#{dest}.incomplete")
URI.open(url, "rb", redirect: true) do |remote|View on GitHub (pinned to 6bd4a54fad)
Solutions
- Update mise to the newest release first — the shim's DSL subset expands as formulae require it
- Install the formula with real Homebrew (`brew install <formula>`) so the full Formula DSL is available, or use a tool backend that ships binaries (aqua/github releases) instead of source-building the brew formula
- If bottles exist for your platform, let mise pour the bottle rather than source-building (bottle pour paths don't evaluate install code and never hit this shim)
- Inspect the formula (github.com/Homebrew/homebrew-core/blob/HEAD/Formula/<first-letter>/<formula>.rb) to find the offending stanza and file an issue at github.com/jdx/mise naming the formula so support can be added
Example fix
# before (source-build shim rejects the formula's DSL) mise use brew:niche-formula # after (real Homebrew handles full DSL) brew install niche-formula
Defensive patterns
Strategy: fallback
Validate before calling
# before source-building, check the formula for DSL the shim rejects
ruby -e '
src = File.read(ARGV[0])
abort "uses testpath in install" if src.match?(/^\s*def install.*?testpath/m)
abort "uses inline patch (:DATA)" if src.include?("patch :DATA") || src.match?(/patch\s+do\s*\n\s*s\s*=/)
abort "resource uses download strategy" if src.match?(/using:\s*:/)
' Formula/foo.rb 2>/dev/null || echo "formula likely needs real brew" Type guard
# ruby: formula source is shim-compatible when no flagged constructs appear
FORMULA_SHIM_UNSUPPORTED = [
/testpath/,
/patch\s+:DATA/,
/using:\s*:/, # resource download strategies
/patch\s+("|')/, # inline patch strings
/on_system\s+:macos\s*=>\s*:(?!ventura_or_older|ventura_or_newer|sonoma_or_older|sonoma_or_newer|monterey_or_older|monterey_or_newer|big_sur_or_older|big_sur_or_newer|catalina_or_older|catalina_or_newer|sequoia_or_older|sequoia_or_newer|tahoe_or_older|tahoe_or_newer)[a-z_]+/
].freeze
def shim_compatible_formula?(src)
FORMULA_SHIM_UNSUPPORTED.none? { |re| src.match?(re) }
end Try / catch
# shell: on shim rejection, fall back to real Homebrew out=$(mise use "brew:$FORMULA" 2>&1) if [ $? -ne 0 ] && printf '%s' "$out" | grep -q 'source-build shim does not support'; then brew install "$FORMULA" else printf '%s\n' "$out" fi
Prevention
- Prefer bottles/derived backends over source-building formulae: bottle pours skip the formula install DSL entirely
- Keep Homebrew available as fallback for formulae with git/svn resources or rich patch sets, which the shim rejects by design
- Update mise when source-build failures appear after homebrew/core formula updates — the DSL subset tracks upstream evolution
- Read the exact feature name in the error (e.g. 'resource with download strategy :git') to decide between updating mise, pinning an older formula, or using brew
When it happens
Trigger: Source-building a formula through mise's brew system-packages integration (e.g. `mise use brew:<formula>` when no bottle is poured/available, or a build mode that forces source) where the formula's `install` block or its resources/patches use unsupported DSL: a `resource do ... using: :git ... end`, a `test do testpath ... end` referenced at install time, a patch with an inline string source, or a helper method the shim never defined.
Common situations: Linux machines or containers source-building formulae that Homebrew serves as bottles on macOS; niche formulae with git/cvs resources or heavy patch sets; a formula update in homebrew/core suddenly adopting a new DSL method the shim lacks; build-from-source forced by settings or missing bottles for the platform.
Related errors
- cask uses `#{feature}`, which mise's cask shim does not supp
- erlang does not yet support refs
- mise outdated --monorepo is not implemented yet
- mise prune --monorepo is not implemented yet
- mise upgrade --monorepo is not implemented yet
AI-assisted analysis of jdx/mise@6bd4a54fad (2026-08-16).
Data as JSON: /api/errors/126a3a6318e78c30.
Report an issue: GitHub.