{"record":{"id":"69b87bcfedc90290","repo":"jdx/mise","slug":"brew-bottles-are-only-published-for-a-formula-s-cu","errorCode":null,"errorMessage":"brew bottles are only published for a formula's current version ('{p}'): pin via the formula name instead (e.g. \"brew:postgresql@17\")","messagePattern":"brew bottles are only published for a formula's current version \\('(.+?)'\\): pin via the formula name instead \\(e\\.g\\. \"brew:postgresql@17\"\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/packages/brew/mod.rs","lineNumber":124,"sourceCode":"        for request in pkgs {\n            let name = request_formula_name(&request.name);\n            let state = linked_package_state(&request.version, pour::linked_state(name));\n            if matches!(state, PackageState::NeedsRepair { .. })\n                && pour::repair_link_record(name, opts.dry_run)?\n            {\n                repaired.push(request.clone());\n            }\n        }\n        Ok(repaired)\n    }\n\n    /// Prefetch bottles concurrently, then install the closure in dependency order.\n    async fn install_via_pour(&self, pkgs: &[PackageRequest], opts: &InstallOpts) -> Result<()> {\n        // bottles only exist for a formula's current version — versioning is\n        // expressed in the formula name itself (postgresql@17); the CLI\n        // filters pinned requests out before calling\n        if let Some(p) = pkgs.iter().find(|p| p.version.is_some()) {\n            bail!(\n                \"brew bottles are only published for a formula's current version ('{p}'): \\\n                 pin via the formula name instead (e.g. \\\"brew:postgresql@17\\\")\"\n            );\n        }\n        let roots: Vec<String> = pkgs.iter().map(|p| p.name.clone()).collect();\n        let closure = resolve::resolve_closure_with_taps(pkgs, !opts.dry_run).await?;\n        for rf in &closure {\n            if rf.on_request\n                && !roots.contains(&rf.formula.name)\n                && let Some(alias) = roots.iter().find(|r| rf.formula.aliases.contains(r))\n            {\n                warn!(\n                    \"'{alias}' is an alias of '{}' — use the canonical name in [bootstrap.packages] \\\n                     so `mise bootstrap packages status` can track it\",\n                    rf.formula.name\n                );\n            }\n        }","sourceCodeStart":106,"sourceCodeEnd":142,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/system/packages/brew/mod.rs#L106-L142","documentation":"mise's brew backend pours prebuilt Homebrew bottles, which exist only for a formula's currently-published version. Pinned versions like `brew:postgresql=17.2` cannot be satisfied by a bottle, so install_via_pour refuses the request and tells you to encode the version in the formula name itself (versioned formulae such as postgresql@17). The CLI is documented to filter pinned requests out before this point, so reaching this error means a pinned request slipped through.","triggerScenarios":"Calling the brew package install/upgrade path (install_via_pour, invoked by install and upgrade) with a PackageRequest whose version field is Some — e.g. `mise bootstrap packages apply` or package install with `brew:foo=1.2.3` syntax that bypassed the CLI's pinned-request filter.","commonSituations":"Writing brew packages directly into mise.toml `[bootstrap.packages]` with an `=` version; scripting against the backend API instead of the CLI; older configs migrated from another tool that used version-pinned brew syntax.","solutions":["Remove the version pin and use the versioned formula name instead: `brew:postgresql@17` rather than `brew:postgresql=17`","Check how the request reached the backend — the CLI should filter pinned brew requests out, so a direct API/scripted caller must do the filtering itself","If you truly need an exact old version not offered as a @-formula, install it with plain `brew` outside mise or use a different backend (e.g. github:, cargo:)"],"exampleFix":"// before\n[bootstrap.packages]\n\"brew:postgresql\" = \"17.2\"\n// after\n[bootstrap.packages]\n\"brew:postgresql@17\" = \"*\"","handlingStrategy":"validation","validationCode":"const pinned = pkgs.filter(p => p.version != null);\nif (pinned.length > 0) {\n  throw new Error(`brew requests must not pin versions: ${pinned.map(p => p.name).join(', ')} — use versioned formula names like postgresql@17`);\n}","typeGuard":"const isUnpinned = (p) => p.version == null;\nconst brewPkgs = pkgs.filter(isUnpinned);","tryCatchPattern":null,"preventionTips":["Always express brew versions via @-formulae (node@20, postgresql@17), never version pins","Route brew package requests through the mise CLI, which filters pinned requests before the backend","Review [bootstrap.packages] entries for `brew:name=version` syntax after migrations"],"tags":["brew","versioning","packages"],"backgroundTag":"unsupported-operation","analyzedSha":"533346cc374382b41ec5ff70536252b2e96e725c","analyzedAt":"2026-09-17T13:35:38.149Z","contentChangedAt":"2026-09-17T13:35:38.149Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}