libnyanpasu/clash-nyanpasu · error
journal destination has a different payload
Error message
journal destination has a different payload
What it means
When transition_journal finds the destination phase journal already present as a regular file, it compares the destination journal's payload with the source journal's. If they differ, it bails instead of overwriting, because two journals with the same operation_id but different payloads indicate corrupted or interleaved transaction state. The library intentionally never silently discards either journal.
Source
Thrown at backend/tauri/src/service/profile_file.rs:1238
root: &Path,
operation_id: &str,
from: JournalLocation,
to: JournalLocation,
) -> anyhow::Result<()> {
let source = Self::journal_path(root, from, operation_id);
let destination = Self::journal_path(root, to, operation_id);
let source_journal = Self::read_journal(&source, operation_id)?;
match std::fs::symlink_metadata(&destination) {
Err(error) if error.kind() == std::io::ErrorKind::NotFound => {
Self::advance_journal_phase(&source, &destination, &source_journal)
}
Ok(metadata) if is_symlink_or_reparse(&metadata) || !metadata.is_file() => bail!(
"journal destination is not a regular file: {}",
destination.display()
),
Ok(_) => {
if Self::read_journal(&destination, operation_id)? != source_journal {
bail!("journal destination has a different payload");
}
Self::remove_private_regular(&source)
}
Err(error) => Err(error).context("inspect journal destination"),
}
}
fn transition_cleanup_journal(
root: &Path,
operation_id: &str,
from: CleanupPhase,
to: CleanupPhase,
) -> anyhow::Result<()> {
let source = Self::cleanup_path(root, from, operation_id);
let destination = Self::cleanup_path(root, to, operation_id);
let source_journal = Self::read_journal(&source, operation_id)?;
match std::fs::symlink_metadata(&destination) {
Err(error) if error.kind() == std::io::ErrorKind::NotFound => {View on GitHub (pinned to f7dbce2997)
Solutions
- Treat the operation as unrecoverable: delete all journal files for that operation_id (both phase locations) and re-run the profile operation from scratch.
- Compare the two journal files at the printed paths to confirm which attempt is newer, and manually remove the stale one if you must salvage it.
- Avoid reusing operation ids across attempts; ensure each materialization generates a fresh id.
- If crashes cause this repeatedly, verify disk integrity (fsck/chkdsk) — torn writes suggest storage-level problems.
Example fix
// before: retrying the transition always re-bails
transition_journal(root, &id, from, to)?;
// after: discard the conflicting operation and start over
for loc in [from, to] {
let _ = std::fs::remove_file(journal_path(root, loc, &id));
}
let prepared = prepare_materialization(...)?; // new operation_id
prepared.commit()?; Defensive patterns
Strategy: try-catch
Validate before calling
fn journal_payloads_agree(root: &Path, from: JournalLocation, to: JournalLocation, id: &str) -> bool {
let (a, b) = (journal_path(root, from, id), journal_path(root, to, id));
match (std::fs::read(a), std::fs::read(b)) {
(Ok(a), Ok(b)) => a == b,
_ => true, // missing destination is fine; transition will create it
}
} Try / catch
match transition_journal(root, id, from, to) {
Err(e) if e.to_string().contains("different payload") => {
// ambiguous transaction: delete all journals for this operation_id and restart
}
other => other?,
} Prevention
- Generate a fresh operation_id for every materialization attempt
- Verify disk health if torn journal payloads recur after crashes
- Do not restore journal directories from partial backups
- Let recovery converge matching duplicates instead of editing journals by hand
When it happens
Trigger: Advancing a journal phase (e.g. staged -> committed for the same operation_id) when the destination already holds a journal written by a different operation/attempt that reused the same operation_id, or a partially-written/damaged journal whose contents no longer match.
Common situations: A crash left both phases populated but the Windows write-through path was interrupted mid-write leaving a torn payload; an operation_id was accidentally regenerated/reused across attempts; a user restored the journal directory from an old backup mixing attempts.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- journal destination is not a regular file: {}
- cleanup journal destination has a different payload
- cleanup journals have conflicting payloads
- cleanup journal destination is not a regular file: {}
- failed to allocate a unique runtime candidate after 16 attem
AI-assisted analysis of libnyanpasu/clash-nyanpasu@f7dbce2997 (2026-09-08).
Data as JSON: /api/errors/62de85644a878233.
Report an issue: GitHub.