jdx/mise · error

dpkg-query failed

Error message

dpkg-query failed: {}

What it means

The apt backend uses `dpkg-query` to check installed package state. dpkg-query exits 1 when some queried packages are simply unknown (treated as 'Missing'), so only other nonzero statuses are errors; mise then raises dpkg-query's stderr.

Solutions

  1. Read the stderr in the message for dpkg's actual complaint
  2. Run `dpkg --configure -a` to repair an interrupted dpkg state
  3. Ensure no other package operation is holding the dpkg lock
  4. Verify manually: dpkg-query -W <package>
Defensive patterns

Strategy: try-catch

Validate before calling

dpkg-query -W -f='${Status}' dpkg >/dev/null 2>&1 || dpkg --configure -a

Try / catch

if let Err(e) = installed(pkgs) {
    if e.to_string().contains("dpkg-query failed") {
        run("dpkg --configure -a");
        retry(pkgs)?;
    }
}

Prevention

When it happens

Trigger: `dpkg-query` exits with a code other than 0 or 1 — dpkg database corruption, lock contention, or dpkg-query binary broken/missing.

Common situations: Interrupted dpkg operation leaving /var/lib/dpkg inconsistent; concurrent package operations holding the dpkg lock; chroot/container with a partial dpkg database.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


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

Appendix: source

Thrown at src/system/packages/apt.rs:193

        if pkgs.is_empty() {
            return Ok(vec![]);
        }
        let mut args = vec![
            "-W".to_string(),
            "-f=${Package}\\t${db:Status-Status}\\t${Version}\\t${Architecture}\\n".to_string(),
        ];
        args.extend(pkgs.iter().map(|p| dpkg_name(&p.name).to_string()));
        debug!("$ dpkg-query {}", args.join(" "));
        let output = tokio::process::Command::new("dpkg-query")
            .args(&args)
            .stdin(Stdio::null())
            .stdout(Stdio::piped())
            .stderr(Stdio::piped())
            .output()
            .await?;
        // exit 1 just means some packages are unknown to dpkg — they're Missing
        if !output.status.success() && output.status.code() != Some(1) {
            bail!(
                "dpkg-query failed: {}",
                String::from_utf8_lossy(&output.stderr).trim()
            );
        }
        let stdout = String::from_utf8_lossy(&output.stdout);
        Ok(parse_dpkg_query(&stdout, pkgs))
    }

    async fn available(&self, names: &[String]) -> Result<Vec<bool>> {
        if names.is_empty() {
            return Ok(vec![]);
        }
        // apt-cache policy heads every stanza with the *bare* package name, so
        // `bash:amd64` reports as `bash:` — an arch qualifier cannot be
        // recovered from a batched result, and matching one by its bare name
        // would call `bash:arm64` installable whenever any `bash` stanza is
        // present. Bare names go in one batch; each qualified name gets its own
        // query, where apt answers by emitting a stanza or nothing at all.

View on GitHub (pinned to 533346cc37)