{"record":{"id":"549879e237f87907","repo":"jdx/mise","slug":"brew-tapped-formula-name-needs-a-github-tap-u","errorCode":null,"errorMessage":"brew: tapped formula '{name}' needs a GitHub tap URL in [bootstrap.brew.taps] so mise can fetch metadata directly without the brew CLI","messagePattern":"brew: tapped formula '(.+?)' needs a GitHub tap URL in \\[bootstrap\\.brew\\.taps\\] so mise can fetch metadata directly without the brew CLI","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/packages/brew/api.rs","lineNumber":163,"sourceCode":"        .wrap_err_with(|| format!(\"failed to fetch Homebrew formula '{name}'\"))\n}\n\npub async fn formula_with_tap_name(\n    name: &str,\n    tap_name: Option<&str>,\n    tap_url: Option<&str>,\n) -> Result<Formula> {\n    let Some((owner, tap, formula_name)) = split_tap_name(name).or_else(|| {\n        let (owner, tap) = split_tap(tap_name?)?;\n        Some((owner, tap, name))\n    }) else {\n        return formula(name).await;\n    };\n    if owner == \"homebrew\" && tap == \"core\" {\n        return formula(formula_name).await;\n    }\n    let Some(url) = tap_formula_api_url(owner, tap, formula_name, tap_url) else {\n        bail!(\n            \"brew: tapped formula '{name}' needs a GitHub tap URL in [bootstrap.brew.taps] \\\n             so mise can fetch metadata directly without the brew CLI\"\n        );\n    };\n    HTTP_FETCH\n        .json_cached::<Formula, _>(url)\n        .await\n        .wrap_err_with(|| {\n            format!(\n                \"failed to fetch Homebrew tap formula '{name}' directly. \\\n                 The tap must publish API metadata at api/formula/{formula_name}.json; \\\n                 mise will not proxy to the brew CLI\"\n            )\n        })\n}\n\npub(super) fn tap_name(name: &str) -> Option<String> {\n    let (owner, tap, _) = split_tap_name(name)?;","sourceCodeStart":145,"sourceCodeEnd":181,"githubUrl":"https://github.com/jdx/mise/blob/9dcfcaa0dc8747a2577d3270b69bb9d8313b2807/src/system/packages/brew/api.rs#L145-L181","documentation":"mise fetches Homebrew formula metadata directly from GitHub (raw.githubusercontent.com) instead of shelling out to the brew CLI. For a formula in a third-party tap (owner/tap/name) it needs the tap's GitHub repository; when a tap URL is configured in [bootstrap.brew.taps] but is not a plain https://github.com/<owner>/<repo> URL (non-GitHub host, SSH URL, or extra path segments), no raw base can be derived and mise refuses rather than silently guessing.","triggerScenarios":"Installing a tapped formula like `mise use brew:user/tap/tool` while [bootstrap.brew.taps] maps that tap to a GitLab/Bitbucket/self-hosted URL, an `git@github.com:...` SSH URL, or a deep link such as https://github.com/owner/repo/tree/main.","commonSituations":"Companies mirroring taps on internal GitLab; users copying clone URLs with extra segments; assuming mise supports non-GitHub taps for CLI-free metadata fetching (it does not).","solutions":["Set the tap entry to the bare repository URL: https://github.com/<owner>/<repo> (.git suffix and trailing slash are tolerated)","If the tap follows the homebrew-<name> convention, delete the URL override entirely — mise infers https://github.com/<owner>/homebrew-<tap> automatically","If the tap is not on GitHub, mise cannot fetch its metadata: install that formula with the brew CLI outside mise"],"exampleFix":"# before\n[bootstrap.brew.taps]\n\"company/tap\" = \"https://gitlab.internal/dev/homebrew-tap\"\n\n# after\n[bootstrap.brew.taps]\n\"company/tap\" = \"https://github.com/company/homebrew-tap\"","handlingStrategy":"validation","validationCode":"fn is_bare_github_url(url: &str) -> bool {\n    let u = url.trim_end_matches(\".git\").trim_end_matches('/');\n    u.strip_prefix(\"https://github.com/\").is_some_and(|rest| {\n        let mut parts = rest.split('/');\n        parts.next().is_some_and(|o| !o.is_empty())\n            && parts.next().is_some_and(|r| !r.is_empty())\n            && parts.next().is_none()\n    })\n}\n\n// before resolving brew:user/tap/tool:\nassert!(tap_url.map_or(true, is_bare_github_url), \"tap URL must be https://github.com/<owner>/<repo>\");","typeGuard":null,"tryCatchPattern":"Catch the bail and point users at the exact config key: [bootstrap.brew.taps].<tap> must be a bare GitHub https URL; do not attempt any non-GitHub fallback (mise has none by design).","preventionTips":["Use plain https://github.com/<owner>/<repo> URLs for every tap entry","Omit the URL for taps named homebrew-<tap>; mise infers the repo","Remember mise never proxies to the brew CLI — non-GitHub taps are simply unsupported"],"tags":["homebrew","brew","tap","github","mise","config"],"backgroundTag":"unsupported-package-source-url","analyzedSha":"9dcfcaa0dc8747a2577d3270b69bb9d8313b2807","analyzedAt":"2026-08-17T14:28:50.624Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}