jdx/mise · error

every selected bottle was prepared

Error message

every selected bottle was prepared

What it means

During Homebrew package install/upgrade via `pour`, bottles are prepared into a map keyed by package index; the install loop then `remove(&index).expect("every selected bottle was prepared")`. The invariant is that every selected index has a prepared bottle; a panic means the preparation loop skipped or failed an index that the install loop still expects, i.e. state divergence between the two phases.

Solutions

  1. Update this code so a missing prepared bottle is reported as an error instead of panicking (record failure like the surrounding `failure` logic does)
  2. Verify the preparation loop inserts an entry for every selected index even on failure paths
  3. Reproduce with the exact package list and check which index is missing from `prepared`

Example fix

// before
let bottle = prepared.remove(&index).expect("every selected bottle was prepared");
// after
let Some(bottle) = prepared.remove(&index) else {
    failure = Some(anyhow!("bottle for {} was not prepared", pkg_version.name));
    break;
};
Defensive patterns

Strategy: try-catch

Validate before calling

// before install: confirm selection and prepared keys align
assert!(selection_indices.iter().all(|i| prepared.contains_key(i)), "unprepared bottle selected");

Try / catch

let Some(bottle) = prepared.remove(&index) else {
    failure = Some(anyhow!("bottle not prepared for index {index}"));
    break;
};

Prevention

When it happens

Trigger: Calling `install`/`upgrade` (src/system/packages/brew/mod.rs:301) where a bottle for a selected package index was never inserted into `prepared` — e.g. preparation short-circuited, a filter dropped an entry, or indices shifted between selection and preparation.

Common situations: Mixed package lists where some entries are casks/formulae filtered out during preparation but still present in the selection; a failed prep that doesn't remove the selection; concurrency changes altering index mapping.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17). Data as JSON: /api/errors/e33a37bb8c20b6ba. Report an issue: GitHub.

Appendix: source

Thrown at src/system/packages/brew/mod.rs:301

                            unreachable!("every selected bottle has a preparation job");
                        };
                        match result {
                            Ok(bottle) => {
                                prepared.insert(completed, bottle);
                            }
                            Err(err) => {
                                reports[completed]
                                    .finish_with_icon("failed".to_string(), ProgressIcon::Error);
                                failure = Some((completed, err));
                            }
                        }
                    }
                    if failure.is_some() {
                        break;
                    }
                    let bottle = prepared
                        .remove(&index)
                        .expect("every selected bottle was prepared");
                    pour::install_prepared(bottle, &**pr).map(|()| pkg_version.clone())
                }
                None => {
                    if failure.is_some() {
                        break;
                    }
                    // Source builds must remain dependency ordered, but they
                    // can safely run alongside bottle download/preparation,
                    // which does not mutate active prefix links.
                    let build = source::build(rf, &closure, &**pr);
                    tokio::pin!(build);
                    let mut jobs_open = true;
                    loop {
                        tokio::select! {
                            // Record a ready bottle failure before a simultaneously
                            // completed source build can advance the install loop.
                            biased;
                            job = bottle_jobs.next(), if jobs_open => match job {

View on GitHub (pinned to 533346cc37)