jdx/mise · error
encrypted file does not match its path: {path}
Error message
encrypted file does not match its path: {path} What it means
The outer encrypted envelope records the logical path of the file it protects. If the envelope's embedded path does not equal the path at which the object was found, decrypt() rejects it, because decrypting would place contents under an identity that does not match the store's record. This prevents path-swap attacks and accidental misplacement.
Source
Thrown at src/system/history/sync/files.rs:258
{
bail!("encrypted file does not match its path or mode: {path}");
}
Ok(())
}
pub(crate) fn decrypt(
repo: &HistoryRepo,
path: &str,
object: &Object,
interactive: bool,
) -> Result<Object> {
let outer = envelope(repo, object, agecrypt::MAX_ENCRYPTED_BYTES)?
.ok_or_else(|| eyre::eyre!("missing encrypted file envelope: {path}"))?;
if control_file(path) {
bail!("setup configuration itself cannot be encrypted: {path}");
}
if outer.path != path {
bail!("encrypted file does not match its path: {path}");
}
if let Some(decrypted) = repo.decrypted_object(&object.1) {
return Ok(decrypted);
}
let bytes = agecrypt::decrypt_sync(&outer.ciphertext.0, interactive)
.wrap_err_with(|| format!("cannot unlock {path}; run mise bootstrap dotfiles pull interactively with a matching age identity"))?;
let inner: Plaintext =
rmp_serde::from_slice(&bytes).wrap_err("invalid encrypted file payload")?;
validate(path, &outer, &inner)?;
let oid = repo.transient_blob_id(&inner.content.0)?;
let decrypted = (inner.mode, oid);
repo.remember_decrypted(&object.1, decrypted.clone());
Ok(decrypted)
}
fn encrypt(
repo: &HistoryRepo,
path: &str,View on GitHub (pinned to afd2eddd3a)
Solutions
- Re-encrypt the file at its new path so the envelope path matches (run the encrypt step of the dotfiles sync).
- Move the file back to its original path, or restore it from origin.
- Run mise bootstrap dotfiles pull to resync envelopes with the authoritative history.
Example fix
// before: envelope for ~/.gitconfig placed at ~/.gitconfig.bak $ git mv ~/.gitconfig ~/.gitconfig.bak // after: re-encrypt under the new path so outer.path matches $ mise bootstrap dotfiles push # re-encrypts and records the new path
Defensive patterns
Strategy: validation
Validate before calling
if envelope_path_for(blob) != target_path {
eprintln!("re-encrypt needed: envelope path mismatch");
} Try / catch
match decrypt(repo, &object, path, interactive) {
Ok(obj) => obj,
Err(e) if e.to_string().contains("does not match its path") => {
eprintln!("{path} was moved; re-encrypting under new path");
reencrypt(path)
}
Err(e) => return Err(e),
} Prevention
- Use the sync's own move/rename flow instead of git mv on encrypted files.
- Re-push (re-encrypt) after any path change.
- Avoid copying .enc blobs to new filenames manually.
When it happens
Trigger: Calling decrypt (via commit_object) on an object whose envelope(outer.path) differs from the requested path — e.g. the file was moved/renamed without re-encrypting, or envelope bytes were copied to another path.
Common situations: git mv on an encrypted file without re-encryption; cherry-pick/merge that relocated an encrypted blob; manually copying an .enc file to a new name.
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
- encrypted file does not match its path or mode: {path}
- task action manifest is not canonical JSON
- remote action descriptor is missing
- remote action metadata is missing
- remote action output file is missing
AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09).
Data as JSON: /api/errors/15b90ebf5e487ee1.
Report an issue: GitHub.