libnyanpasu/clash-nyanpasu · error
cleanup journal destination is not a regular file: {}
Error message
cleanup journal destination is not a regular file: {} What it means
Same guard as the materialization transition, but for the cleanup journal family: transition_cleanup_journal moves a cleanup journal between CleanupPhase locations (e.g. Pending -> Ready). If the destination cleanup-journal path exists as a symlink/reparse point or a non-regular file, the library refuses rather than writing through it. This protects the cleanup recovery path from foreign or hostile artifacts.
Source
Thrown at backend/tauri/src/service/profile_file.rs:1259
}
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 => {
Self::advance_journal_phase(&source, &destination, &source_journal)
}
Ok(metadata) if is_symlink_or_reparse(&metadata) || !metadata.is_file() => bail!(
"cleanup journal destination is not a regular file: {}",
destination.display()
),
Ok(_) => {
if Self::read_journal(&destination, operation_id)? != source_journal {
bail!("cleanup journal destination has a different payload");
}
Self::remove_private_regular(&source)
}
Err(error) => Err(error).context("inspect cleanup journal destination"),
}
}
fn discard_materialization(
root: &Path,
operation_id: &str,
location: JournalLocation,
) -> anyhow::Result<()> {View on GitHub (pinned to f7dbce2997)
Solutions
- Remove the symlink/non-file artifact at the reported destination path and retry the cleanup.
- Exclude the profiles private journal directory from cloud sync and antivirus real-time scanning.
- Abandon the cleanup by deleting all cleanup journals for that operation_id, then re-plan the cleanup.
- On Windows, confirm the path is not under a OneDrive 'files on demand' folder; download contents locally.
Example fix
// before: transition fails repeatedly
transition_cleanup_journal(root, &id, CleanupPhase::Pending, CleanupPhase::Ready)?;
// after: clear the non-file destination first
let dest = cleanup_path(root, CleanupPhase::Ready, &id);
let meta = std::fs::symlink_metadata(&dest)?;
if meta.is_symlink() || !meta.is_file() {
std::fs::remove_file(&dest)?;
}
transition_cleanup_journal(root, &id, CleanupPhase::Pending, CleanupPhase::Ready)?; Defensive patterns
Strategy: try-catch
Validate before calling
fn cleanup_destination_ok(root: &Path, to: CleanupPhase, id: &str) -> bool {
match std::fs::symlink_metadata(cleanup_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_cleanup_journal(root, id, from, to) {
Err(e) if e.to_string().contains("cleanup journal destination is not a regular file") => {
// remove the foreign artifact at the printed path, retry once
}
other => other?,
} Prevention
- Keep the cleanup journal directory out of cloud-sync and antivirus scanning
- Avoid manual probing that leaves directories in cleanup phase slots
- On Windows, force local availability of profile folders under OneDrive
- Clear the entire operation state when artifacts look foreign
When it happens
Trigger: Running profile cleanup recovery (transitioning the cleanup journal from Pending to Ready) when cleanup_path(root, to, operation_id) exists as a symlink, directory, or Windows reparse point — e.g. a sync client replaced the file or someone probed the cleanup directory manually.
Common situations: Cloud-drive placeholder reparse points on Windows intercepting the cleanup journal path; leftover test scaffolding that created a directory at the cleanup phase path; antivirus quarantining the journal and leaving a stub.
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 is not a regular file: {}
- cleanup journal destination has a different payload
- pending cleanup journal is not a regular file
- ready cleanup journal is not a regular file
- cleanup journals have conflicting payloads
AI-assisted analysis of libnyanpasu/clash-nyanpasu@f7dbce2997 (2026-09-08).
Data as JSON: /api/errors/4a8a5c00a3d5a589.
Report an issue: GitHub.