jdx/mise · error
lockfile generation would change the recorded signer…
Error message
lockfile generation would change the recorded signer; previous files were preserved
What it means
The lockfile records the signer identity (and `attested_by`) used to verify artifacts. `ensure_no_downgrade` bails if regeneration would record a different signer or attestation authority than the existing entry, preserving the previous files. This prevents silently re-trusting artifacts under a new signing identity.
Solutions
- Verify the signer change is legitimate (check the project's release announcements/key rotation) before proceeding
- Update or remove the existing lockfile entry deliberately so the new signer is consciously accepted
- Pin generation to the artifact source that uses the original signer
- Regenerate the lockfile from a trusted checkout after reviewing the new signer fingerprint
Example fix
# before: blindly regenerating after upstream key rotation mise lock --all # after: review then explicitly refresh mise lock --all # after confirming new signer fingerprint via project announcements
Defensive patterns
Strategy: validation
Validate before calling
if let Some(old_signer) = &existing.signer {
if new.signer.as_ref() != Some(old_signer) || new.attested_by != existing.attested_by {
// signer changed — confirm upstream key rotation before regenerating
}
} Prevention
- Track upstream signing-key/attestation announcements for locked dependencies
- Diff the recorded signer field after lockfile regeneration and review changes
- Avoid switching backends for already-locked tools without re-verifying signatures
- Pin generation to the original artifact source
When it happens
Trigger: Regenerating a lockfile where the old entry has `signer: Some(...)` but the newly computed entry has a different signer, or a different `attested_by` value — e.g. the packslip manifest switched signing keys or a different attestation authority now signs the release.
Common situations: A project rotated its release signing key; mise switched between GitHub attestations and a project's own signing identity; a mirror serves artifacts signed by a different party; packslip manifest updated signer metadata.
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
- lockfile generation would downgrade additional artifact…
- lockfile generation would downgrade recorded provenance…
- lockfile requires Ruby provenance but GitHub attestations…
- packslip: : this release . If the vendor announced the…
- Python locks require credential-free HTTP artifact URLs…
AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17).
Data as JSON: /api/errors/5a49c69ec3715812.
Report an issue: GitHub.
Appendix: source
Thrown at src/lockfile/generate.rs:790
// artifact authenticated by its signed release manifest. Older incremental
// lock updates could carry detected GitHub provenance into a Packslip entry,
// but complete generation intentionally does not persist that unverified
// link. Without a signer, retain the ordinary provenance ratchet.
let packslip_signer_replaces_provenance =
backend.starts_with("packslip:") && new.signer.is_some();
if provenance_is_downgrade(
old.provenance.as_ref(),
new.provenance.as_ref(),
packslip_signer_replaces_provenance,
) {
bail!(
"lockfile generation would downgrade recorded provenance; previous files were preserved"
);
}
if let Some(signer) = &old.signer
&& (new.signer.as_ref() != Some(signer) || new.attested_by != old.attested_by)
{
bail!(
"lockfile generation would change the recorded signer; previous files were preserved"
);
}
// Preserve identities across reordering, then pair replaced URLs in their
// configured order so version upgrades retain the previous trust baseline.
let mut replacements = new.additional_artifacts.iter().filter(|artifact| {
!old.additional_artifacts
.iter()
.any(|old| old.url == artifact.url)
});
for artifact in &old.additional_artifacts {
let replacement = new
.additional_artifacts
.iter()
.find(|new| new.url == artifact.url)
.or_else(|| replacements.next());
if provenance_is_downgrade(
artifact.provenance.as_ref(),View on GitHub (pinned to 533346cc37)