libnyanpasu/clash-nyanpasu · error

backup file is not a regular file

Error message

backup file is not a regular file

What it means

read_backup_resource validates that the backed-up file blob is a regular file before using it for rollback. The backup file path exists but is a symlink/reparse point or otherwise not a regular file, so it cannot be trusted as a restorable backup and the operation aborts.

Source

Thrown at backend/tauri/src/service/profile_file.rs:858

            Err(error) => {
                return Err(error)
                    .with_context(|| format!("inspect backup file {}", file_path.display()));
            }
        };
        let link_metadata = match std::fs::symlink_metadata(&link_path) {
            Ok(metadata) => Some(metadata),
            Err(error) if error.kind() == std::io::ErrorKind::NotFound => None,
            Err(error) => {
                return Err(error)
                    .with_context(|| format!("inspect backup link {}", link_path.display()));
            }
        };
        if file_metadata.is_some() && link_metadata.is_some() {
            bail!("materialization has multiple backups");
        }
        if let Some(metadata) = file_metadata {
            if is_symlink_or_reparse(&metadata) || !metadata.is_file() {
                bail!("backup file is not a regular file");
            }
            return Ok(Some(StoredResource::File { path: file_path }));
        }
        if let Some(metadata) = link_metadata {
            if is_symlink_or_reparse(&metadata) || !metadata.is_file() {
                bail!("backup symlink specification is not a regular file");
            }
            let target = std::fs::read_to_string(&link_path)?;
            return Ok(Some(StoredResource::Symlink {
                target: ExternalProfilePath::new(target)?,
            }));
        }
        Ok(None)
    }

    fn create_ready_link(
        root: &Path,
        operation_id: &str,

View on GitHub (pinned to f7dbce2997)

Solutions

  1. Clear the backup area for this operation_id and re-run the materialization so a fresh regular-file backup is captured.
  2. Relocate the backup root to a plain local filesystem.
  3. Check for tools (backup/sync/AV) converting files into links inside the backup directory.
  4. If the original target still exists as a valid file/symlink, you can re-run capture_backup by redoing the materialization.
Defensive patterns

Strategy: validation

Validate before calling

let md = std::fs::symlink_metadata(backup_file_path)?;
if md.is_symlink() || !md.is_file() {
    std::fs::remove_file(backup_file_path)?; // drop unusable backup before retry
}

Type guard

fn is_regular_file_node(p: &Path) -> bool {
    std::fs::symlink_metadata(p).map(|m| !m.is_symlink() && m.is_file()).unwrap_or(false)
}

Try / catch

match result {
    Err(e) if e.to_string().contains("backup file is not a regular file") => {
        clear_backup_dir(root, op_id)?;
        retry()
    }
    other => other,
}

Prevention

When it happens

Trigger: backup_file_path(root, operation_id) exists but symlink_metadata reports a symlink/reparse point or a non-regular file — the backup blob was replaced by a link, or the backup root lives on a filesystem that reports special file types (network mount, Windows reparse).

Common situations: Tampering or accidental modification of the backup directory; backup root on OneDrive/NFS/overlay storage; sync tools rewriting stored blobs as links; manual copy operations that dereferenced/converted files.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of libnyanpasu/clash-nyanpasu@f7dbce2997 (2026-09-08). Data as JSON: /api/errors/48192d54ee363047. Report an issue: GitHub.