libnyanpasu/clash-nyanpasu · error
ready cleanup journal is not a regular file
Error message
ready cleanup journal is not a regular file
What it means
Identical guard to the Pending phase, applied to the Ready cleanup journal: if the Ready phase path exists as a symlink/reparse point or non-regular file, locate_cleanup refuses to continue. Recovery requires both phase slots to be either absent or plain regular files so that payloads can be compared safely.
Source
Thrown at backend/tauri/src/service/profile_file.rs:1348
) -> anyhow::Result<Option<(CleanupPhase, MaterializationJournal)>> {
if !valid_operation_id(operation_id) {
bail!("invalid profile cleanup operation id");
}
let pending_path = Self::cleanup_path(root, CleanupPhase::Pending, operation_id);
let ready_path = Self::cleanup_path(root, CleanupPhase::Ready, operation_id);
let pending = match std::fs::symlink_metadata(&pending_path) {
Ok(metadata) if !is_symlink_or_reparse(&metadata) && metadata.is_file() => {
Some(Self::read_journal(&pending_path, operation_id)?)
}
Ok(_) => bail!("pending cleanup journal is not a regular file"),
Err(error) if error.kind() == std::io::ErrorKind::NotFound => None,
Err(error) => return Err(error).context("inspect pending cleanup journal"),
};
let ready = match std::fs::symlink_metadata(&ready_path) {
Ok(metadata) if !is_symlink_or_reparse(&metadata) && metadata.is_file() => {
Some(Self::read_journal(&ready_path, operation_id)?)
}
Ok(_) => bail!("ready cleanup journal is not a regular file"),
Err(error) if error.kind() == std::io::ErrorKind::NotFound => None,
Err(error) => return Err(error).context("inspect ready cleanup journal"),
};
match (pending, ready) {
(None, None) => Ok(None),
(Some(journal), None) => Ok(Some((CleanupPhase::Pending, journal))),
(None, Some(journal)) => Ok(Some((CleanupPhase::Ready, journal))),
(Some(pending), Some(ready)) if pending == ready => {
Self::remove_private_regular(&pending_path)?;
Ok(Some((CleanupPhase::Ready, ready)))
}
(Some(_), Some(_)) => bail!("cleanup journals have conflicting payloads"),
}
}
fn has_materialization_journal(root: &Path, operation_id: &str) -> bool {
JournalLocation::ALL.iter().any(|location| {
std::fs::symlink_metadata(Self::journal_path(root, *location, operation_id)).is_ok()View on GitHub (pinned to f7dbce2997)
Solutions
- Delete or replace the non-file artifact at the reported Ready path and rerun the lookup.
- Make the journal directory local-only (exclude from cloud sync/space-saver placeholders).
- Clear the entire cleanup operation state for that operation_id and restart the cleanup from scratch.
- Audit what wrote to the journal directory if this recurs — external tooling is interfering.
Example fix
// before
let state = locate_cleanup(root, &id)?; // bails on Ready artifact
// after
let r = cleanup_path(root, CleanupPhase::Ready, &id);
let meta = std::fs::symlink_metadata(&r)?;
if meta.is_symlink() || !meta.is_file() {
std::fs::remove_file(&r)?;
}
let state = locate_cleanup(root, &id)?; Defensive patterns
Strategy: validation
Validate before calling
fn ready_journal_clean(root: &Path, id: &str) -> Result<bool, std::io::Error> {
match std::fs::symlink_metadata(cleanup_path(root, CleanupPhase::Ready, id)) {
Err(e) if e.kind() == std::io::ErrorKind::NotFound => Ok(true),
Err(e) => Err(e),
Ok(m) => Ok(!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 locate_cleanup(root, id) {
Err(e) if e.to_string().contains("ready cleanup journal is not a regular file") => {
// clear the non-file Ready artifact, then rerun the lookup
}
other => other,
} Prevention
- Make journal directories local-only; disable cloud placeholders for them
- Never leave test scaffolding in the cleanup phase directory
- Clear the full operation state instead of patching individual phase slots
- Verify profile folders are not under 'files on demand' management on Windows
When it happens
Trigger: Cleanup lookup/recovery for an operation whose Ready cleanup journal path (cleanup_path(root, CleanupPhase::Ready, operation_id)) exists as a symlink, directory, or Windows reparse point — typically sync-client placeholders or manual/test tampering.
Common situations: Crash-recovery run on a machine where OneDrive 'files on demand' turned the Ready journal into a cloud placeholder; CI or scripts leaving directories in the journal folder; security tools substituting files.
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
- pending cleanup journal is not a regular file
- 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/9fe3b0543c41f500.
Report an issue: GitHub.