{"record":{"id":"540f6196fb63e201","repo":"Hmbown/CodeWhale","slug":"snapshot-path-is-not-a-regular-file","errorCode":null,"errorMessage":"snapshot path is not a regular file","messagePattern":"snapshot path is not a regular file","errorType":"validation","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/snapshot/repo.rs","lineNumber":694,"sourceCode":"                \"-z\",\n                id.as_str(),\n                \"--\",\n                rel.to_str()\n                    .ok_or_else(|| io_other(\"restore path must be UTF-8\"))?,\n            ],\n        )?;\n        if !entry.status.success() {\n            return Err(io_other(format!(\n                \"Failed to inspect snapshot file: {}\",\n                String::from_utf8_lossy(&entry.stderr).trim()\n            )));\n        }\n        if entry.stdout.is_empty() {\n            return Ok(false);\n        }\n        if !(entry.stdout.starts_with(b\"100644 blob \") || entry.stdout.starts_with(b\"100755 blob \"))\n        {\n            return Err(io::Error::new(\n                io::ErrorKind::InvalidInput,\n                \"snapshot path is not a regular file\",\n            ));\n        }\n        Ok(true)\n    }\n\n    /// Return whether `rel` differs between snapshot `id` and the current\n    /// working tree.\n    ///\n    /// This is the single-path counterpart of\n    /// [`Self::work_tree_matches_snapshot`]: it answers \"would restoring just\n    /// this file change anything?\", which is what file-scoped revert\n    /// cursoring needs. A path that exists in neither the snapshot nor the\n    /// working tree does not differ.\n    pub fn path_differs_from_snapshot(&self, id: &SnapshotId, rel: &Path) -> io::Result<bool> {\n        let in_work = self.validate_restore_file(rel)?;\n        let in_target = self.snapshot_contains_regular_file(id, rel)?;","sourceCodeStart":676,"sourceCodeEnd":712,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/snapshot/repo.rs#L676-L712","documentation":"snapshot_contains_regular_file runs `git cat-file -p <rev>:<path>` (via entry.stdout) against the snapshot repo and requires the mode line to be `100644 blob` or `100755 blob`. If the snapshot entry exists but is not a regular blob (e.g. a symlink `120000` or gitlink `160000` recorded in the snapshot commit), this InvalidInput error fires — the restore path only supports regular files.","triggerScenarios":"Calling path_differs_from_snapshot or restore_paths_checked for a path whose snapshot entry is a symlink or submodule (gitlink) rather than a normal blob.","commonSituations":"A symlink or submodule was committed into the snapshot before the regular-file restriction existed; restoring from a snapshot created when symlinks were allowed.","solutions":["Exclude the path from restore; only regular-file snapshot entries can be restored through this API.","Convert the symlink/submodule in the workspace to a regular file and take a fresh snapshot.","Restore the path manually with git commands if the old snapshot entry is needed."],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":"fn is_regular_blob(mode_line: &[u8]) -> bool {\n    mode_line.starts_with(b\"100644 blob \")\n        || mode_line.starts_with(b\"100755 blob \")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Skip symlink/submodule entries when scripting restores.","Prefer fresh snapshots over pre-restriction ones for restore operations.","List snapshot entry modes before choosing restore paths."],"tags":["snapshots","git","file-type"],"backgroundTag":"unsupported-operation","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}