{"record":{"id":"6ceea377c8f807e7","repo":"jdx/mise","slug":"tap-tap-must-be-in-owner-repo-format-supp","errorCode":null,"errorMessage":"tap '{tap}' must be in <owner>/<repo> format; supply an explicit URL for non-standard taps","messagePattern":"tap '(.+?)' must be in <owner>/<repo> format; supply an explicit URL for non-standard taps","errorType":"validation","errorClass":"eyre::Report","httpStatus":null,"severity":"error","filePath":"src/system/packages/brew/maintenance.rs","lineNumber":91,"sourceCode":"    #[serde(default)]\n    installed_on_request: Option<bool>,\n    #[serde(default)]\n    source: Option<ReceiptSource>,\n}\n\n#[derive(Debug, Default, Deserialize)]\nstruct ReceiptSource {\n    #[serde(default)]\n    tap: Option<String>,\n}\n\npub fn default_tap_url(tap: &str) -> Result<String> {\n    let mut parts = tap.split('/');\n    match (parts.next(), parts.next(), parts.next()) {\n        (Some(owner), Some(repo), None) if !owner.is_empty() && !repo.is_empty() => {\n            Ok(format!(\"https://github.com/{owner}/homebrew-{repo}.git\"))\n        }\n        _ => bail!(\n            \"tap '{tap}' must be in <owner>/<repo> format; supply an explicit URL for non-standard taps\"\n        ),\n    }\n}\n\npub fn linked_formulae(include_all: bool) -> Result<Vec<InstalledFormula>> {\n    let opt = prefix::prefix().join(\"opt\");\n    let mut formulae = BTreeMap::new();\n    for entry in file::ls(&opt)? {\n        if !entry\n            .symlink_metadata()\n            .is_ok_and(|m| m.file_type().is_symlink())\n        {\n            continue;\n        }\n        let Some(name) = entry\n            .file_name()\n            .and_then(|f| f.to_str())","sourceCodeStart":73,"sourceCodeEnd":109,"githubUrl":"https://github.com/jdx/mise/blob/9dcfcaa0dc8747a2577d3270b69bb9d8313b2807/src/system/packages/brew/maintenance.rs#L73-L109","documentation":"When importing installed Homebrew formulae, taps absent from the config get a GitHub URL derived by strict convention: the tap must be exactly <owner>/<repo> with both parts non-empty, mapping to https://github.com/<owner>/homebrew-<repo>.git. Any other shape — single segment, three segments, empty parts — cannot be mapped and must be supplied explicitly.","triggerScenarios":"system import (brew) -> InstalledFormula::tap_entry_with_urls -> default_tap_url(tap) when the tap is not a key in [bootstrap.brew.taps]. Fails for taps like 'mytap', 'team/internal/tools', or 'owner/' found in a formula's install receipt (Tab/ReceiptSource.tap).","commonSituations":"Machines using private or nonstandard tap names (no owner/repo shape); taps cloned from non-GitHub forges; receipts with malformed tap strings; importing after someone hand-created taps.","solutions":["Add an explicit URL for the tap in the target config: [bootstrap.brew.taps].\"<tap>\" = \"https://git.example.com/group/homebrew-tap.git\", then re-run import","Rename the local tap to a proper <owner>/<repo> form so the GitHub convention applies","Skip importing formulae from that tap (remove/untap it first) if it is not needed"],"exampleFix":"# before: tap 'internal-tools' fails URL derivation\n# system import -> tap 'internal-tools' must be in <owner>/<repo> format\n\n# after: supply the URL explicitly in the target config\n[bootstrap.brew.taps]\n\"internal-tools\" = \"https://git.mycorp.com/dev/homebrew-internal-tools.git\"","handlingStrategy":"validation","validationCode":"// Validate tap shape before import; only <owner>/<repo> maps to a default URL.\nfn tap_has_default_url(tap: &str) -> bool {\n    let mut parts = tap.split('/');\n    matches!((parts.next(), parts.next(), parts.next()),\n        (Some(owner), Some(repo), None) if !owner.is_empty() && !repo.is_empty())\n}","typeGuard":"fn is_standard_tap(tap: &str) -> bool {\n    let mut p = tap.split('/');\n    matches!((p.next(), p.next(), p.next()), (Some(o), Some(r), None) if !o.is_empty() && !r.is_empty())\n}","tryCatchPattern":"// Supply explicit URLs for nonstandard taps instead of relying on the default:\nlet url = configured_taps\n    .get(tap)\n    .cloned()\n    .map(Ok)\n    .unwrap_or_else(|| default_tap_url(tap))\n    .wrap_err_with(|| format!(\"add [bootstrap.brew.taps].\\\"{tap}\\\" = \\\"<git-url>\\\" to the target config\"))?;","preventionTips":["Keep taps in <owner>/<repo> form (GitHub convention) so URLs derive automatically","Pre-populate [bootstrap.brew.taps] with explicit URLs for private or non-GitHub taps before running system import","Reject or rename malformed tap strings at the source rather than at import time"],"tags":["brew","tap","import","config","url"],"backgroundTag":"invalid-identifier-format","analyzedSha":"9dcfcaa0dc8747a2577d3270b69bb9d8313b2807","analyzedAt":"2026-08-17T14:28:50.624Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}