xai-org/grok-build · error · anyhow::Error
bare repository has no working directory
Error message
bare repository has no working directory
What it means
find_worktree_root discovers a git repository at `path` with gix and then requires a working directory. Bare repositories (created with `git init --bare` or clones ending in `.git` with no checkout) have `workdir() == None`, so the function cannot return a worktree root and throws this error.
Source
Thrown at crates/codegen/xai-fast-worktree/src/git/discovery.rs:59
worktree_path.display()
)
}
}
/// Find the worktree root (working directory root) for a path.
///
/// This handles both regular repositories and worktrees correctly.
/// For a regular repo at `/repo`, returns `/repo`.
/// For a worktree at `/worktrees/wt1`, returns `/worktrees/wt1`.
/// For a subdirectory `/repo/subdir`, returns `/repo`.
pub(crate) fn find_worktree_root(path: &Path) -> Result<PathBuf> {
let repo = gix::discover(path)
.with_context(|| format!("failed to discover git repo at {}", path.display()))?;
// workdir() returns the working directory root for both repos and worktrees
let work_dir = repo
.workdir()
.ok_or_else(|| anyhow::anyhow!("bare repository has no working directory"))?;
Ok(work_dir.to_path_buf())
}
/// Get the HEAD commit hash using gix.
pub(crate) fn get_head_commit(path: &Path) -> Result<String> {
let repo = gix::discover(path)
.with_context(|| format!("failed to discover git repo at {}", path.display()))?;
let head = repo
.head()
.context("failed to get HEAD")?
.peel_to_commit()
.context("failed to peel HEAD to commit")?;
Ok(head.id().to_string())
}
View on GitHub (pinned to bc7f02eddd)
Solutions
- Pass the path of a non-bare checkout (the directory containing a working tree) instead of the bare repo
- Clone the repository non-bare (`git clone <url>`) and operate on the clone
- If you intentionally need a working area from a bare repo, use `git worktree add` against it and pass the new worktree path
Example fix
// before
let root = find_worktree_root(Path::new("/srv/repo.git"))?;
// after
let root = find_worktree_root(Path::new("/srv/checkout"))?; // non-bare clone Defensive patterns
Strategy: validation
Validate before calling
fn has_workdir(path: &Path) -> bool {
gix::discover(path).map(|r| r.workdir().is_some()).unwrap_or(false)
}
// before: assert repo_path is a non-bare checkout
git::discover_guard(&repo_path)?; Type guard
fn non_bare_repo(path: &Path) -> Option<std::path::PathBuf> {
gix::discover(path).ok()?.workdir().map(|p| p.to_path_buf())
} Try / catch
match find_worktree_root(path) {
Ok(root) => root,
Err(e) if e.to_string().contains("bare repository") => {
return Err(anyhow!("{} is a bare repo; pass a checkout instead", path.display()))
}
Err(e) => return Err(e),
} Prevention
- Point tools at a working-tree checkout, never at `repo.git` or a server-side bare repo
- Check `git rev-parse --is-bare-repository` before invoking the API
- Avoid passing a `.git` directory as the repo path
- In CI, clone non-bare (or add a worktree) when a working directory is required
When it happens
Trigger: Calling find_worktree_root (or any API built on it) with a path pointing to a bare repository — e.g. a central server-side repo, a `.git` directory passed directly, or `--bare` clones.
Common situations: Pointing tooling at a remote/origin bare repo on a server or NAS; passing a repo's internal `.git` directory instead of the checkout root; CI setups that use bare clones for caching.
Related errors
- invalid .git file format: {}
- failed to discover git repo: {e}
- bare git repository: {}
- cannot read working files from bare repository
- cannot read files from bare repository
AI-assisted analysis of xai-org/grok-build@bc7f02eddd (2026-08-31).
Data as JSON: /api/errors/8894215ddba2c71c.
Report an issue: GitHub.