libnyanpasu/clash-nyanpasu · error
journal destination is not a regular file: {}
Error message
journal destination is not a regular file: {} What it means
During a crash-recovery journal phase transition (transition_journal), the library moves the transaction journal from one phase location to the next. If the destination path already exists but is a symlink/reparse point or a non-regular file (directory, fifo, etc.) instead of a normal journal file, it refuses to proceed. This guards the atomic journal-directory invariant: something external has placed a non-file artifact where the next journal phase belongs.
Source
Thrown at backend/tauri/src/service/profile_file.rs:1232
let _ = journal;
Self::rename_journal_same_filesystem(source, destination)
}
}
fn transition_journal(
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,View on GitHub (pinned to f7dbce2997)
Solutions
- Inspect the path printed in the message and remove or replace the symlink/non-file artifact with nothing (let the library recreate it), then retry the operation.
- Check for cloud-sync/backup interference in the profiles' private journal directory and exclude it from syncing.
- Discard the whole interrupted operation by removing all journal files for that operation_id, then re-run the materialization from scratch.
- If this recurs on Windows, scan for reparse-point placeholders produced by OneDrive 'files on demand' and make the profiles directory locally available.
Example fix
// before: blindly retrying the transition keeps failing
transition_journal(root, id, JournalLocation::Staged, JournalLocation::Committed)?;
// after: clear the bogus destination artifact first
let dest = journal_path(root, JournalLocation::Committed, &id);
let meta = std::fs::symlink_metadata(&dest)?;
if meta.is_symlink() || !meta.is_file() {
std::fs::remove_file(&dest)?; // or remove_dir_all for a directory
}
transition_journal(root, id, JournalLocation::Staged, JournalLocation::Committed)?; Defensive patterns
Strategy: try-catch
Validate before calling
fn journal_destination_ok(root: &Path, to: JournalLocation, id: &str) -> bool {
match std::fs::symlink_metadata(journal_path(root, to, id)) {
Err(e) => e.kind() == std::io::ErrorKind::NotFound,
Ok(m) => !m.is_symlink() && m.is_file(),
}
} Type guard
fn is_plain_file(m: &std::fs::Metadata) -> bool {
!m.is_symlink() && m.is_file()
} Try / catch
match transition_journal(root, id, from, to) {
Err(e) if e.to_string().contains("journal destination is not a regular file") => {
// remove the foreign artifact, then retry once
}
other => other?,
} Prevention
- Exclude the private journal directory from cloud sync, backup, and antivirus tools
- Never create files or directories manually inside the journal directory while debugging
- On Windows, keep profile folders outside OneDrive 'files on demand' scope
- Treat unexpected journal-directory contents as corruption and clear the whole operation
When it happens
Trigger: Calling any journal transition (e.g. committing a prepared profile materialization) when the destination phase journal path (journal_path(root, to, operation_id)) exists as a symlink or directory — typically because a previous run crashed mid-write and something else (an editor, antivirus quarantine, a sync tool) replaced the artifact, or because a test/manual probe created a directory there.
Common situations: Crash recovery after power loss where OneDrive/Dropbox or a backup tool substituted the journal file with a placeholder or reparse point on Windows; a developer manually inspecting the private journal directory and leaving a directory behind; automated cleanup tools that convert stale files into shortcuts.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- journal destination has a different payload
- cleanup journal destination is not a regular file: {}
- runtime candidate directory is a symlink or reparse point: {
- profile directory is a symlink, reparse point, or non-direct
- materialization journal is not a regular file: {}
AI-assisted analysis of libnyanpasu/clash-nyanpasu@f7dbce2997 (2026-09-08).
Data as JSON: /api/errors/e96066c85e206ae6.
Report an issue: GitHub.