{"record":{"id":"efcb9cc9873eeb85","repo":"GitoxideLabs/gitoxide","slug":"required-file-does-not-exist","errorCode":null,"errorMessage":"Required file '{}' does not exist","messagePattern":"Required file '(.+?)' does not exist","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gix/src/worktree/proxy.rs","lineNumber":49,"sourceCode":"            git_dir: git_dir.into(),\n        }\n    }\n\n    pub(crate) fn new_if_gitdir_file_exists(parent: &'repo Repository, git_dir: impl Into<PathBuf>) -> Option<Self> {\n        let git_dir = git_dir.into();\n        if git_dir.join(\"gitdir\").is_file() {\n            Some(Proxy::new(parent, git_dir))\n        } else {\n            None\n        }\n    }\n}\n\nimpl Proxy<'_> {\n    fn dot_git(&self) -> std::io::Result<PathBuf> {\n        let git_dir = self.git_dir.join(\"gitdir\");\n        gix_discover::path::from_plain_file_relative_to_file(&git_dir).ok_or_else(|| {\n            std::io::Error::new(\n                std::io::ErrorKind::NotFound,\n                format!(\"Required file '{}' does not exist\", git_dir.display()),\n            )\n        })?\n    }\n\n    /// Read the location of the checkout, the base of the work tree.\n    /// Note that the location might not exist.\n    pub fn base(&self) -> std::io::Result<PathBuf> {\n        Ok(gix_discover::path::without_dot_git_dir(self.dot_git()?))\n    }\n\n    /// The git directory for the work tree, typically contained within the parent git dir.\n    pub fn git_dir(&self) -> &Path {\n        &self.git_dir\n    }\n\n    /// The name of the worktree, which is derived from its folder within the `worktrees` directory within the parent `.git` folder.","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/GitoxideLabs/gitoxide/blob/e73179060badf27222d790981fac3f84c1830a7e/gix/src/worktree/proxy.rs#L31-L67","documentation":"The worktree `Proxy::dot_git()` helper reads the `.git` plain file (a worktree's pointer file containing `gitdir: <path>`). If `<worktree>/.git` cannot be parsed as a plain file, an io::Error with NotFound is returned with this message naming the path.","triggerScenarios":"Calling methods like `base()` or `is_prunable()` on a linked-worktree proxy when the `<worktree>/.git` file is missing or unreadable (e.g. the worktree was pruned/deleted while its directory remains).","commonSituations":"Stale linked worktrees whose registration was removed (`git worktree prune`) leaving a dangling directory; manually copied worktree directories without the `.git` pointer file; permission problems making `.git` unreadable.","solutions":["Verify the worktree directory contains a `.git` file (not a directory) pointing at a valid gitdir.","Remove stale worktrees: run `git worktree prune` or `git worktree remove <path>` and skip deleted worktrees.","Check the `.git` file contents start with `gitdir: ` and the target path exists and is readable."],"exampleFix":"// before\nlet dot_git = wt.proxy().dot_git().expect(\"worktree valid\");\n\n// after\nlet dot_git_path = wt.path().join(\".git\");\nif !dot_git_path.is_file() {\n    eprintln!(\"skipping stale worktree at {}\", wt.path().display());\n    continue;\n}","handlingStrategy":"validation","validationCode":"let git_file = wt.path().join(\".git\");\nif !git_file.is_file() {\n    // stale or non-worktree directory: skip\n}\nif let Ok(text) = std::fs::read_to_string(&git_file) {\n    let ok = text.strip_prefix(\"gitdir: \").map(|t| Path::new(t.trim()).exists()).unwrap_or(false);\n}","typeGuard":"fn is_valid_worktree(path: &Path) -> bool {\n    path.join(\".git\").is_file()\n}","tryCatchPattern":"match proxy_call() {\n    Ok(v) => v,\n    Err(e) if e.kind() == std::io::ErrorKind::NotFound => skip_stale_worktree(),\n    Err(e) => return Err(e.into()),\n}","preventionTips":["Run `git worktree prune` before enumerating worktrees","Skip directories without a `.git` plain file","Check that the gitdir target inside the `.git` file exists"],"tags":["git","worktree","io","file-not-found"],"backgroundTag":"file-not-found","analyzedSha":"e73179060badf27222d790981fac3f84c1830a7e","analyzedAt":"2026-09-08T11:26:50.865Z","contentChangedAt":"2026-09-08T11:26:50.865Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}