jdx/mise · error · RuntimeError
formula has no stable URL
Error message
formula has no stable URL
What it means
After eval'ing the formula file, mise checks that the Formula subclass recorded a stable source URL via the `url ...` DSL call. If the subclass never called `url` (or called it with nil), `klass.source_url` is nil and this raise fires. mise builds third-party formulas from source, so it requires a resolvable stable download URL.
Source
Thrown at src/system/packages/brew/tap_formula_metadata.rb:217
def head(*) = nil
def livecheck(*) = nil
def service(*) = nil
def test(*) = nil
def method_missing(*) = nil
def respond_to_missing?(*) = true
end
end
def inferred_version(url)
basename = File.basename(url.to_s).sub(/\.(tar\.(gz|xz|bz2|zst)|tgz|txz|zip|gz)\z/i, "")
match = basename.match(/(?:^|[-_v])([0-9]+(?:\.[0-9A-Za-z]+)+(?:[-_.][0-9A-Za-z]+)*)/)
match && match[1]
end
eval(STDIN.read.force_encoding("UTF-8"), TOPLEVEL_BINDING, FORMULA_FILE, 1)
klass = Formula.instance_variable_get(:@subclass)
raise "no Formula subclass found" unless klass
raise "formula has no stable URL" if klass.source_url.to_s.empty?
raise "formula has no stable sha256" if klass.source_sha256.to_s.empty?
version = (klass.explicit_version || inferred_version(klass.source_url)).to_s
raise "could not infer formula version; add an explicit version declaration" if version.to_s.empty?
metadata = {
"name" => FORMULA_NAME,
"tap" => ENV.fetch("MISE_BREW_TAP"),
"versions" => { "stable" => version },
"revision" => klass.revision_value || 0,
"keg_only" => klass.keg_only_value || false,
"dependencies" => klass.runtime_dependencies || [],
"build_dependencies" => klass.build_dependencies || [],
"bottle" => {},
"urls" => { "stable" => { "url" => klass.source_url, "checksum" => klass.source_sha256 } },
"ruby_source_path" => ENV.fetch("MISE_BREW_SOURCE_PATH"),
"ruby_source_checksum" => { "sha256" => ENV.fetch("MISE_BREW_SOURCE_CHECKSUM") },
"tap_git_head" => ENV.fetch("MISE_BREW_TAP_COMMIT")
}View on GitHub (pinned to afd2eddd3a)
Solutions
- Ensure the formula has a top-level `url "https://..."` inside `stable` (or class body) that executes unconditionally
- If the url is inside a conditional block (on_macos/on_arm/on_system), confirm the host env vars (MISE_BREW_OS, arch) match so the branch executes, or move the url out of the conditional
- Update the stub extractor if the formula uses an unrecognized DSL method that swallows the url call
- Pin/modify the formula to a version with a plain stable url declaration
Example fix
// before // class Foo < Formula // head "https://example.com/foo.git" # no stable url // end // after // class Foo < Formula // url "https://example.com/foo-1.2.3.tar.gz" // sha256 "abc123..." // head "https://example.com/foo.git" // end
Defensive patterns
Strategy: validation
Validate before calling
body = File.read(formula_path) raise "formula lacks a stable url declaration" unless body.match?(/^\s*url\s+["']https?:\/\//)
Type guard
def has_stable_url?(formula_source) formula_source.match?(/^\s*url\s+["'][^"']+["']/) end
Try / catch
begin extract_formula_metadata(formula_path) rescue RuntimeError => e raise unless e.message == "formula has no stable URL" warn "Formula has no stable url; it is likely head-only or uses unsupported DSL" end
Prevention
- Only use formulas that declare a top-level stable `url`
- Prefer formulas over head-only ones for source builds
- Keep MISE_BREW_OS/arch env vars correct so conditional url blocks execute
- Avoid formulas relying on Homebrew DSL features the lightweight stub swallows
When it happens
Trigger: The formula declares its source only in a block the extractor skipped (e.g. only inside `head`, a `resource`, or a conditional `on_macos`/`on_arm` block that didn't run on the host), uses a DSL construct the stub swallows via `method_missing` (which returns nil and discards the url), or simply omits `url` in `stable`.
Common situations: Formulas relying on Homebrew features this lightweight stub does not model (e.g. urls set through custom DSL or strategies inside unexecuted conditionals); formulas with only `head` specs and no stable URL; formulas using url only inside `deprecate!`/disabled paths; a formula whose stable block calls url on a platform branch that doesn't match the host.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- no Formula subclass found
- formula has no stable sha256
- could not infer formula version; add an explicit version dec
- brew casks are installed at their current version ('{p}')
- brew-cask:{}: dependency cycle detected
AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09).
Data as JSON: /api/errors/c57c130c32a8b6c0.
Report an issue: GitHub.