{"record":{"id":"9412306b7ed076d2","repo":"jdx/mise","slug":"formula-has-no-stable-source-url","errorCode":null,"errorMessage":"{}: formula has no stable source URL","messagePattern":"(.+?): formula has no stable source URL","errorType":"validation","errorClass":"eyre::Report","httpStatus":null,"severity":"error","filePath":"src/system/packages/brew/source.rs","lineNumber":64,"sourceCode":"}\n\n/// why `has_bottle` is false, for log/dry-run output\npub fn missing_bottle_reason(formula: &Formula) -> String {\n    match formula.bottle_files() {\n        Some(files) if !files.is_empty() => {\n            let mut tags: Vec<String> = files.keys().cloned().collect();\n            tags.sort();\n            format!(\"bottles exist only for: {}\", tags.join(\", \"))\n        }\n        _ => \"source-only formula, no bottles\".to_string(),\n    }\n}\n\n/// Reject early what the source builder cannot handle, with the reason —\n/// checked before any work happens so dry-run and real runs fail alike.\npub fn check_buildable(formula: &Formula) -> Result<()> {\n    let Some(src) = formula.stable_url() else {\n        bail!(\"{}: formula has no stable source URL\", formula.name);\n    };\n    if let Some(using) = &src.using {\n        bail!(\n            \"{}: source uses the {using:?} download strategy, which mise cannot build from \\\n             (and no bottle exists for this machine)\",\n            formula.name,\n        );\n    }\n    if src.checksum.is_none() {\n        bail!(\"{}: source archive has no sha256 in the API\", formula.name);\n    }\n    // the formula .rb must be pinned to the API snapshot's commit and\n    // verifiable — evaluating a newer/unverified formula against older\n    // source metadata would build the wrong thing\n    if formula.ruby_source_path.is_none() {\n        bail!(\"{}: API metadata has no ruby_source_path\", formula.name);\n    }\n    if formula.tap_git_head.is_none() {","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/jdx/mise/blob/9dcfcaa0dc8747a2577d3270b69bb9d8313b2807/src/system/packages/brew/source.rs#L46-L82","documentation":"When no bottle exists for the host and mise would build a formula from source, check_buildable first validates the formula's API metadata so dry-run and real runs fail identically before any work. A formula with no stable source URL — head-only formulae — cannot be built, so it is rejected with this error.","triggerScenarios":"check_buildable runs on a formula whose stable_url() returns None; this path is reached because the host tag had no matching bottle (see the sibling hint listing which tags do have bottles).","commonSituations":"Installing niche head-only formulae; formulae whose bottles exist only for other platforms/architectures; deprecated formulae whose stable spec was dropped upstream.","solutions":["Install the tool with native Homebrew, which supports head-only formulae (`brew install --HEAD`)","Pick an alternative formula or version that ships stable sources or a bottle for your platform","Build and install the tool manually outside mise if you need exactly that head version"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"# check the formula shape before relying on a source build\nmise exec -- brew info <formula> 2>/dev/null | grep -q 'stable' || echo \"head-only formula — mise cannot build it; use native brew or another formula\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Prefer formulae that ship stable sources or bottles for your platform","Head-only or platform-skipped formulae must be installed with native Homebrew","Read the sibling hint in mise's output — it lists which tags do have bottles"],"tags":["brew","source-build","formula-metadata"],"backgroundTag":"no-stable-release-available","analyzedSha":"9dcfcaa0dc8747a2577d3270b69bb9d8313b2807","analyzedAt":"2026-08-17T14:28:50.624Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}