jdx/mise · error · eyre::Report

mise oci cannot mix apk and apt entries in [bootstrap.packag

Error message

mise oci cannot mix apk and apt entries in [bootstrap.packages]; use the package manager matching the selected base image

What it means

collect_package_requests refuses configurations where `[bootstrap.packages]` contains entries for BOTH apk and apt. The system-packages feature produces exactly one layer via one package manager, and no base image can serve both package systems, so mise aborts before unpacking the rootfs rather than attempting a doomed install.

Source

Thrown at src/oci/packages.rs:199

            continue;
        }
        match mgr.manager.name() {
            "apk" => apk.extend(mgr.requests.clone()),
            "apt" => apt.extend(mgr.requests.clone()),
            other => unsupported.push(other.to_string()),
        }
    }
    if !unsupported.is_empty() {
        unsupported.sort();
        unsupported.dedup();
        bail!(
            "mise oci currently supports only apt and apk entries in [bootstrap.packages]; \
             unsupported manager(s): {}",
            unsupported.join(", ")
        );
    }
    if !apk.is_empty() && !apt.is_empty() {
        bail!(
            "mise oci cannot mix apk and apt entries in [bootstrap.packages]; use the package \
             manager matching the selected base image"
        );
    }
    if !apk.is_empty() {
        Ok(Some((OciPackageManager::Apk, apk)))
    } else if !apt.is_empty() {
        Ok(Some((OciPackageManager::Apt, apt)))
    } else {
        Ok(None)
    }
}

fn unpack_base_layers(layout: &ImageLayout, layers: &[Descriptor], rootfs: &Path) -> Result<()> {
    for layer in layers {
        let path = layout.blob_path(&layer.digest);
        let reader = open_layer_reader(layer, &path)?;
        let mut archive = Archive::new(reader);

View on GitHub (pinned to 9dcfcaa0dc)

Solutions

  1. Keep only the table matching the selected base image: delete `[bootstrap.packages.apt]` for an Alpine/Wolfi base, or `[bootstrap.packages.apk]` for a Debian/Ubuntu base
  2. Verify the base image actually in use (`FROM alpine:*` → apk, `FROM debian:*`/`ubuntu:*` → apt) before deciding which table survives
  3. Search all layered mise.tomls — the conflicting table may come from a parent config, not the project file

Example fix

# before (mise.toml)
[bootstrap.packages.apk]
curl = "any"
[bootstrap.packages.apt]
ripgrep = "any"

# after — Alpine base, apk only
[bootstrap.packages.apk]
curl = "any"
ripgrep = "any"
Defensive patterns

Strategy: validation

Validate before calling

// Before `mise oci build`, assert the config does not carry both managers.
fn validate_single_manager(cfg: &toml::Table) -> Result<(), String> {
    let Some(pkgs) = cfg.get("bootstrap").and_then(|b| b.get("packages")).and_then(|p| p.as_table()) else {
        return Ok(());
    };
    let has_apk = pkgs.get("apk").is_some_and(|v| !v.as_table().unwrap_or(&toml::Table::new()).is_empty());
    let has_apt = pkgs.get("apt").is_some_and(|v| !v.as_table().unwrap_or(&toml::Table::new()).is_empty());
    if has_apk && has_apt {
        return Err("[bootstrap.packages] mixes apk and apt; keep only the manager matching the base image".into());
    }
    Ok(())
}

Type guard

fn uses_single_package_manager(cfg: &toml::Table) -> bool {
    let keys = ["apk", "apt"];
    keys.iter().filter(|k| table_non_empty(cfg, k)).count() <= 1
}

Prevention

When it happens

Trigger: mise.toml has non-empty `[bootstrap.packages.apk]` and `[bootstrap.packages.apt]` tables at the same time (possibly merged from layered config files), then `mise oci build` runs.

Common situations: Copy-pasting package examples from both Alpine and Debian docs into one file; merging config from a teammate whose base image differs; gradual base-image migration leaving stale entries from the previous distro.

Understand the failure class

Background: Config validation failed: what "invalid value for {key}" and settings-rejection errors mean across 19 open-source libraries — this error's family across 19 libraries.

Related errors


AI-assisted analysis of jdx/mise@9dcfcaa0dc (2026-08-17). Data as JSON: /api/errors/7491c5cf1ac4b4a5. Report an issue: GitHub.