{"record":{"id":"9a36d96bcb571f50","repo":"helix-editor/helix","slug":"working-tree-not-found","errorCode":null,"errorMessage":"working tree not found","messagePattern":"working tree not found","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"warning","filePath":"helix-vcs/src/git.rs","lineNumber":151,"sourceCode":"    let (repo_path, _trust_from_ownership) = gix::discover::upwards_opts(path, discover_options)\n        .context(\"failed to discover git repo\")?;\n    let (git_dir, _work_dir) = repo_path.into_repository_and_work_tree_directories();\n\n    let options = gix::open::Options::default()\n        .permissions(permissions)\n        // `git_dir` is the discovered `.git` directory (or a linked-worktree git dir), so open it\n        // as-is rather than letting gix append `.git` again.\n        .open_path_as_is(true)\n        .with(trust);\n\n    Ok(ThreadSafeRepository::open_opts(git_dir, options)?)\n}\n\n/// Emulates the result of running `git status` from the command line.\nfn status(repo: &Repository, f: impl Fn(Result<FileChange>) -> bool) -> Result<()> {\n    let work_dir = repo\n        .workdir()\n        .ok_or_else(|| anyhow::anyhow!(\"working tree not found\"))?\n        .to_path_buf();\n\n    let status_platform = repo\n        .status(gix::progress::Discard)?\n        // Here we discard the `status.showUntrackedFiles` config, as it makes little sense in\n        // our case to not list new (untracked) files. We could have respected this config\n        // if the default value weren't `Collapsed` though, as this default value would render\n        // the feature unusable to many.\n        .untracked_files(UntrackedFiles::Files)\n        // Turn on file rename detection, which is off by default.\n        .index_worktree_rewrites(Some(Rewrites {\n            copies: None,\n            percentage: Some(0.5),\n            limit: 1000,\n            ..Default::default()\n        }));\n\n    // No filtering based on path","sourceCodeStart":133,"sourceCodeEnd":169,"githubUrl":"https://github.com/helix-editor/helix/blob/079a789e8cb08ead67f19e1971a1b7438b37354b/helix-vcs/src/git.rs#L133-L169","documentation":"helix's git diff provider (helix-vcs/src/git.rs) emulates `git status` via gix and requires a worktree: status() calls repo.workdir() and errors with 'working tree not found' when it returns None. gix returns None for bare repositories — repos without a checkout, e.g. created with `git init --bare`, server-side mirrors (*.git), or when helix is opened directly inside a .git directory. The error is delivered to the changed-files callback, so VCS features (changed-file picker, diff gutter) are simply unavailable there.","triggerScenarios":"Opening helix inside a bare repository directory (dotfiles.git, a server mirror) or inside a repo's .git directory, then opening the changed-files picker or relying on diff signs.","commonSituations":"Dotfiles managed as a bare repo; exploring mirror/backup repos; accidentally opening .git internals as a project root.","solutions":["Open helix in an actual checkout/worktree of that repository instead of the bare directory.","If the directory is intentionally bare, ignore the error — there is no worktree to diff, so gutter/picker VCS features cannot work.","For dotfile bare repos, edit the checked-out files in $HOME and keep the bare repo out of your editing root."],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":"// skip VCS work when the repo is bare (gix::open honours discovery of .git)\nif let Ok(repo) = gix::open(cwd) {\n    if repo.is_bare() { /* no worktree: skip status/diff queries */ }\n}","typeGuard":"fn has_worktree(path: &std::path::Path) -> bool {\n    gix::open(path).map(|repo| !repo.is_bare()).unwrap_or(false)\n}","tryCatchPattern":"// provider callback: distinguish expected bare-repo errors from real ones\nf(move |res| match res {\n    Ok(change) => handle(change),\n    Err(e) if e.to_string().contains(\"working tree not found\") => true, // expected: bare repo, skip\n    Err(e) => { log::warn!(\"vcs: {e}\"); true }\n});","preventionTips":["Root editor sessions in checkouts, not bare repos or .git internals.","Treat 'working tree not found' as an expected no-op signal in VCS integrations, not a failure to retry."],"tags":["git","vcs","bare-repository"],"backgroundTag":null,"analyzedSha":"079a789e8cb08ead67f19e1971a1b7438b37354b","analyzedAt":"2026-08-16T09:09:59.668Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}