jdx/mise · error

apk info failed: {}

Error message

apk info failed: {}

What it means

mise's Alpine package backend runs `apk info <pkgs>` to learn which requested packages are already installed. apk exits nonzero when a named package is missing but still prints installed versions, so mise only treats the run as failed when the exit is nonzero AND stderr contains something other than blank or 'not found' lines. This error means apk itself reported a genuine failure, so the installed/missing report cannot be trusted.

Source

Thrown at src/system/packages/apk.rs:95

        debug!("$ apk {}", args.join(" "));
        let output = tokio::process::Command::new("apk")
            .args(&args)
            .stdin(Stdio::null())
            .stdout(Stdio::piped())
            .stderr(Stdio::piped())
            .output()
            .await?;
        // apk info exits nonzero when any named package is not installed, but
        // still prints installed package versions. Treat unexpected stderr as
        // real apk failure instead of silently reporting everything missing.
        let stderr = String::from_utf8_lossy(&output.stderr);
        if !output.status.success()
            && !stderr.is_empty()
            && !stderr
                .lines()
                .all(|l| l.trim().is_empty() || l.contains("not found"))
        {
            bail!("apk info failed: {}", stderr.trim());
        }
        let stdout = String::from_utf8_lossy(&output.stdout);
        Ok(parse_apk_info(&stdout, pkgs))
    }

    async fn install(&self, pkgs: &[PackageRequest], opts: &InstallOpts) -> Result<()> {
        let mut args = vec!["add".to_string()];
        if opts.update {
            args.push("--update-cache".to_string());
        }
        args.push("--".to_string());
        args.extend(pkgs.iter().map(apk_name));
        if opts.dry_run {
            miseprintln!("{}", sudo::argv("apk", &args).join(" "));
            return Ok(());
        }
        sudo::run("apk", &args, &[])
    }

View on GitHub (pinned to 9dcfcaa0dc)

Solutions

  1. Reproduce manually: run `apk info <package>` and read the stderr echoed in the message
  2. Repair the package database: `apk update && apk fix` (or `apk verify`)
  3. If apk itself is stale or foreign, upgrade it: `apk add --upgrade apk`
  4. If apk cannot be made healthy (stripped container image), stop declaring apk packages in mise and install them in the Dockerfile instead
Defensive patterns

Strategy: retry

Validate before calling

async fn apk_info_healthy() -> bool {
    tokio::process::Command::new("apk")
        .args(["info", "--installed"])
        .stdin(std::process::Stdio::null())
        .stdout(std::process::Stdio::null())
        .stderr(std::process::Stdio::piped())
        .output()
        .await
        .map(|o| o.status.success() || o.stderr.is_empty())
        .unwrap_or(false)
}

Try / catch

Match the error message prefix "apk info failed" and treat it as an environment failure: surface it to the user and stop — never fall back to reporting all requested packages as missing, because a broken apk database makes that classification a lie.

Prevention

When it happens

Trigger: Any mise flow that inspects apk-managed packages (bootstrap, prune, or config entries using the apk backend) while the underlying `apk info` invocation writes a real error to stderr: unreadable or corrupted /lib/apk/db/installed, an apk binary from a mismatched Alpine release, or broken cache/repo state.

Common situations: Minimal or flattened Alpine container images where the apk database was deleted; mixing Alpine edge/stable repos leaving apk half-upgraded; running mise inside chroot/proot where apk's paths don't resolve; CI images that strip /lib/apk.

Related errors


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