{"record":{"id":"36dc85709134a6fe","repo":"jdx/mise","slug":"path-is-not-in-either-snapshot","errorCode":null,"errorMessage":"{path} is not in either snapshot","messagePattern":"(.+?) is not in either snapshot","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/history/shadow.rs","lineNumber":874,"sourceCode":"            || !super::sync::files::encrypted_paths(self, Some(b))?.is_empty()\n        {\n            return self.decrypted_diff(a, b, opts);\n        }\n        let (from, to) = match &opts.paths {\n            Some((from_path, to_path)) => {\n                let from = format!(\"{a}:{from_path}\");\n                let to = format!(\"{b}:{to_path}\");\n                match (self.object_type(&from)?, self.object_type(&to)?) {\n                    (Some(_), Some(_)) => (from, to),\n                    (Some(kind), None) => (from, self.empty_object(&kind)?),\n                    (None, Some(kind)) => (self.empty_object(&kind)?, to),\n                    (None, None) => {\n                        let path = if from_path == to_path {\n                            from_path.clone()\n                        } else {\n                            format!(\"{from_path} / {to_path}\")\n                        };\n                        bail!(\"{path} is not in either snapshot\");\n                    }\n                }\n            }\n            None => (a.to_string(), b.to_string()),\n        };\n        let call = PlumbingCall::new([\n            \"diff\",\n            \"--no-ext-diff\",\n            \"--exit-code\",\n            if opts.patch { \"--patch\" } else { \"--stat\" },\n            if opts.color {\n                \"--color=always\"\n            } else {\n                \"--color=never\"\n            },\n            &from,\n            &to,\n        ]);","sourceCodeStart":856,"sourceCodeEnd":892,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/system/history/shadow.rs#L856-L892","documentation":"When diffing two snapshots, the code resolves each requested path in the 'from' and 'to' trees. If the path is found in neither snapshot, no comparison is possible and the diff bails with a message naming both path forms.","triggerScenarios":"Calling diff with a path filter that matches no entry in either the from-snapshot or the to-snapshot.","commonSituations":"Typo in the path argument; the file was untracked in both snapshots; using a path relative to the wrong root or an absolute path where a snapshot-relative path is expected.","solutions":["List the snapshot contents to find the correct path spelling, then retry with the exact path","Omit the path filter to diff the whole snapshot","Verify you are comparing the intended pair of checkpoints/refs that actually contain the file"],"exampleFix":"// before\nhistory diff a b --path \".config/nvim/init.vim\"\n\n// after (actual tracked path)\nhistory diff a b --path \"home/.config/nvim/init.vim\"","handlingStrategy":"try-catch","validationCode":"// Rust: confirm the path exists in at least one snapshot before diffing\nlet in_from = from_tree.entry_for(path).is_some();\nlet in_to = to_tree.entry_for(path).is_some();\nanyhow::ensure!(in_from || in_to, \"path {path} absent from both snapshots\");","typeGuard":null,"tryCatchPattern":"match differ.diff(from, to, Some(path)) {\n    Err(e) if e.to_string().contains(\"is not in either snapshot\") => {\n        eprintln!(\"path not tracked in these snapshots; listing available paths...\");\n    }\n    other => other?,\n}","preventionTips":["Copy paths from snapshot listings rather than typing them","Remember paths are snapshot-root-relative (home/..., config/..., fs/...)","Diff without a path filter first to discover valid paths"],"tags":["diff","snapshot","path"],"backgroundTag":"resource-not-found","analyzedSha":"afd2eddd3a50c16190efc1c7e94404b48f72af57","analyzedAt":"2026-09-09T01:38:25.179Z","contentChangedAt":"2026-09-09T01:38:25.179Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}