jdx/mise · error

: sha256 is , the packslip says

Error message

{name}: sha256 is {actual}, the packslip says {}

What it means

fetch_files verifies each downloaded subject against the sha256 recorded in the packslip manifest. When a file's actual digest differs from — or is absent from — the manifest, the downloaded file is deleted and this error is raised to prevent installing tampered or mismatched content.

Solutions

  1. Refresh/regenerate the packslip so its digests match the current upstream release
  2. Check whether the upstream release was updated and re-pin to the intended version
  3. Verify your network path (proxy/mirror) is not altering downloads
  4. If the file legitimately is not a subject, correct the packslip entry so its name/digest mapping matches

Example fix

// before (packslip.toml)
// [[subject]] name = "skill.tar.gz" sha256 = "aaa..."
// after: update to the digest of the file actually published
// [[subject]] name = "skill.tar.gz" sha256 = "bbb..."  # sha256sum skill.tar.gz
Defensive patterns

Strategy: validation

Validate before calling

// compare digests before installing
const expected = statement.digestOf(name);
const actual = await sha256File(dest);
if (expected && expected !== actual) throw new Error(`${name}: digest mismatch`);

Try / catch

try { await fetchFiles(...) } catch (e) { if (/sha256 is .*the packslip says/.test(e.message)) { refreshPackslip(); } else { throw e; } }

Prevention

When it happens

Trigger: The archive/skill downloaded from the URL hashes to a different value than statement.digest_of(name) expects, or the packslip lists no digest for the file it landed on (name is not a subject).

Common situations: Upstream re-released a file under the same URL (digest changed), packslip is stale relative to the project's release, a proxy/mirror served modified content, a filename in the packslip changed so no expected digest exists.

Understand the failure class

Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.

Related errors


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

Appendix: source

Thrown at src/packslip.rs:371

                    let Some(url) = &resource.url else {
                        warn!("{}: asset {name} has no download URL", tv.style());
                        continue;
                    };
                    pr.set_message(format!("download {name}"));
                    file::create_dir_all(dest.parent().unwrap_or(&base))?;
                    // The tool is installed by now and the asset is an extra:
                    // one that cannot be fetched is reported, not fatal. One
                    // that arrives with the wrong digest is another matter.
                    if let Err(err) = download_file(url, &dest, Some(pr)).await {
                        let _ = file::remove_all(&dest);
                        warn!("{}: could not fetch {name}: {err}", tv.style());
                        continue;
                    }
                    let (actual, _) = packslip::digest_file(&dest)?;
                    let expected = statement.digest_of(name);
                    if expected != Some(actual.as_str()) {
                        let _ = file::remove_all(&dest);
                        bail!(
                            "{name}: sha256 is {actual}, the packslip says {}",
                            expected.unwrap_or("it is not a subject")
                        );
                    }
                }
                // The archive and the unpacked skill are separate: an archive
                // left by an earlier attempt still needs unpacking.
                if resource.kind == "skill"
                    && let Some(skill) = skill_name(resource)
                {
                    let dir = base.join("skills").join(skill);
                    // Like the other skill sources: a skill that cannot be
                    // unpacked is reported, and the tool still installs. The
                    // digest check above stays fatal.
                    if !dir.join("SKILL.md").is_file()
                        && let Err(err) = unpack_skill(&dest, &dir, pr)
                    {
                        warn!("{}: could not unpack skill {skill}: {err}", tv.style());

View on GitHub (pinned to 533346cc37)