{"record":{"id":"abace10effde00b0","repo":"Hmbown/CodeWhale","slug":"fleet-file-must-be-regular-and-not-linked","errorCode":null,"errorMessage":"Fleet file must be regular and not linked","messagePattern":"Fleet file must be regular and not linked","errorType":"validation","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/fleet/files.rs","lineNumber":302,"sourceCode":"    }\n\n    pub(crate) fn open_update(&self, create: bool, append: bool) -> io::Result<File> {\n        use std::os::windows::fs::OpenOptionsExt;\n        let file = std::fs::OpenOptions::new()\n            .read(true)\n            .write(true)\n            .append(append)\n            .create(create)\n            .truncate(false)\n            .share_mode(0x0000_0007)\n            .custom_flags(0x0020_0000)\n            .open(self.directory.join(&self.filename))?;\n        let metadata = file.metadata()?;\n        if !metadata.is_file()\n            || crate::plugins::metadata_is_link_or_reparse(&metadata)\n            || crate::plugins::windows_file_identity(&file)?.links != 1\n        {\n            return Err(io::Error::new(\n                io::ErrorKind::InvalidData,\n                \"Fleet file must be regular and not linked\",\n            ));\n        }\n        Ok(file)\n    }\n\n    pub(crate) fn open_file(&self) -> io::Result<File> {\n        // Existing protected reader rejects reparse points, hard links and\n        // non-regular files, and denies concurrent writes/replacement.\n        crate::plugins::manifest::open_bundle_file(&self.directory.join(&self.filename))\n    }\n\n    pub(crate) fn publish(&self, bytes: &[u8]) -> io::Result<()> {\n        self.atomic_write(bytes, false)\n    }\n\n    pub(crate) fn replace(&self, bytes: &[u8]) -> io::Result<()> {","sourceCodeStart":284,"sourceCodeEnd":320,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/fleet/files.rs#L284-L320","documentation":"This error means the Fleet artifact opened for update on Windows (or via the metadata check path) is not a regular file, appears to be a link/reparse point per its metadata, or has a link count other than 1. The library throws it from open_update to keep confined artifact I/O on plain, singly-linked regular files.","triggerScenarios":"Calling open_update when the file is a symlink/junction (metadata_is_link_or_reparse true), a non-regular file type, or windows_file_identity reports links != 1 (a hard link exists).","commonSituations":"An NTFS hard link was created to the artifact; the artifact path was replaced by a symlink; the artifact is a directory or device; a dedupe/backup tool created alternate links.","solutions":["Remove the extra hard link or replace the symlink with a real file, then retry","Delete the artifact and let Codewhale recreate it as a fresh regular file","Verify with fsutil hardlink list <artifact> that only one link exists"],"exampleFix":"// before\nmklink artifact.json real.json  # symlink\n// after\ncopy real.json artifact.json  # regular file, single link","handlingStrategy":"validation","validationCode":"let md = std::fs::symlink_metadata(path)?;\nif !md.is_file() {\n    return Err(\"artifact is not a regular file (symlink/junction or special file)\");\n}\n// on Windows verify link count via GetFileInformationByHandle before updating","typeGuard":null,"tryCatchPattern":"match open_update(ws) {\n    Ok(f) => edit(f),\n    Err(e) if e.kind() == std::io::ErrorKind::InvalidData => {\n        eprintln!(\"artifact is a link or multi-linked; recreate it\");\n    }\n    Err(e) => return Err(e.into()),\n}","preventionTips":["Avoid symlinks/junctions inside the Fleet workspace directory","Run `fsutil hardlink list` when integrity errors appear","Recreate artifacts rather than restoring them from link-preserving backups"],"tags":["windows","filesystem","symlink","hardlink","integrity"],"backgroundTag":"internal-invariant-violation","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-22T11:17:16.035Z"}