libnyanpasu/clash-nyanpasu · critical
promoted target hash mismatch
Error message
promoted target hash mismatch
What it means
promote_resource verifies the final target after replacement by hashing it; the hash differs from expected_hash. This is the last-line integrity check ensuring the promoted file content is exactly what was staged and journaled, so a mismatch aborts the operation as failed rather than reporting success with corrupted data.
Source
Thrown at backend/tauri/src/service/profile_file.rs:944
})?;
}
StoredResource::Symlink {
target: link_target,
} => {
let ready = Self::create_ready_link(root, operation_id, &link_target)?;
self.ensure_managed_parent(target)?;
Self::ensure_replaceable_target(target)?;
replace_atomic(&ready, target).with_context(|| {
format!(
"promote staged symlink {} -> {}",
ready.display(),
target.display()
)
})?;
}
}
if Self::path_hash(target)? != expected_hash {
bail!("promoted target hash mismatch");
}
Ok(())
}
fn backup_hash(root: &Path, operation_id: &str) -> anyhow::Result<String> {
match Self::read_backup_resource(root, operation_id)? {
Some(StoredResource::File { path }) => {
let content = std::fs::read(&path)
.with_context(|| format!("read backup file {}", path.display()))?;
Ok(hash_tagged(b"file", &content))
}
Some(StoredResource::Symlink { target }) => {
Ok(hash_tagged(b"symlink", target.as_str().as_bytes()))
}
None => Ok(ABSENT_HASH.to_owned()),
}
}
View on GitHub (pinned to f7dbce2997)
Solutions
- Rerun the whole materialization with a fresh operation id so a clean staged copy replaces the corrupted target.
- Restore the target from the operation's backup (read_backup_resource / backup restore path) and re-attempt promote.
- Investigate what concurrently modified the target (sync tools, editors, antivirus) and exclude the profile directory.
- Verify disk health if corruption repeats across operations.
Example fix
// before // target modified by another process during promote -> hash mismatch // after // close/sync tools writing to profiles dir, then: client.compensate(root, operation_id).await?; let new_id = client.prepare_materialization(&managed_path, resource).await?; client.promote(root, &new_id).await?;
Defensive patterns
Strategy: try-catch
Validate before calling
let hash = hash_file(&target_path)?;
if hash != expected_hash {
// target already diverged; restore from backup or re-materialize before promote
restore_from_backup(root, op_id, &target_path)?;
} Type guard
fn target_matches_expected(target: &Path, expected: &str) -> bool {
hash_file(target).map(|h| h == expected).unwrap_or(false)
} Try / catch
match client.promote(root, op_id).await {
Err(e) if e.to_string().contains("hash mismatch") => {
// rollback to backup, then retry with a fresh operation
client.compensate(root, op_id).await?;
let fresh = client.prepare_materialization(&managed_path, resource).await?;
client.promote(root, &fresh).await
}
r => r,
} Prevention
- Hold an exclusive lock or pause sync/edit tools while promoting profile files.
- Never write to the managed target path from outside the materialization API.
- Keep staging and targets on the same reliable local filesystem.
- Run reconcile on startup and surface hash mismatches to the user rather than ignoring them.
When it happens
Trigger: promote() completed its copy/rename steps but the resulting target hashes differently — e.g. concurrent writes to the target, a copy that read a source mutated mid-flight, filesystem corruption, or the staged resource itself was tampered with after its hash check.
Common situations: Another process (editor, sync client) wrote the target during promotion; staged source was modified between prepare and promote; disk/filesystem errors silently corrupting content; target on a network mount with unreliable semantics.
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
- staged resource is missing and target hash does not match
- materialization journal operation id mismatch
- staged file hash mismatch
- staged symlink hash mismatch
- cannot complete materialization with a target hash mismatch
AI-assisted analysis of libnyanpasu/clash-nyanpasu@f7dbce2997 (2026-09-08).
Data as JSON: /api/errors/f14fdd8ba4b113b7.
Report an issue: GitHub.