xai-org/grok-build · error · anyhow::Error
not a git repository: {}
Error message
not a git repository: {} What it means
In git_gate's root-discovery path (spawn_blocking around discover_git_root), a NotARepo result bails with 'not a git repository: <path>'. This gate runs before operations are allowed, refusing to proceed when the probe path has no git repository ancestor.
Source
Thrown at crates/codegen/xai-grok-workspace/src/session/git_gate.rs:645
fn forget_cached_roots(root: &Path) {
ROOT_CACHE.lock().retain(|_, entry| entry.root != root);
}
async fn canonical_git_root(path: &Path) -> Result<PathBuf> {
let cwd = dunce::canonicalize(path).unwrap_or_else(|_| path.to_path_buf());
if let Some(root) = lookup_cached_root(&cwd) {
return Ok(root);
}
let probe = cwd.clone();
let discovered = tokio::task::spawn_blocking(move || discover_git_root(&probe))
.await
.map_err(|error| anyhow!("git discover task failed: {error}"))?;
let discovered = match discovered {
GitDiscoveryResult::Found(root) => root,
GitDiscoveryResult::NotARepo => {
anyhow::bail!("not a git repository: {}", path.display())
}
GitDiscoveryResult::DiscoveryFailed(error) => {
return Err(error).context(format!("git discover failed for {}", path.display()));
}
};
let root = dunce::canonicalize(&discovered).unwrap_or(discovered);
store_cached_root(cwd, root.clone());
Ok(root)
}
#[cfg(test)]
#[path = "git_gate_tests.rs"]
mod tests;
View on GitHub (pinned to bc7f02eddd)
Solutions
- cd into (or configure the workspace to point at) a directory inside a git repository
- Verify with `git rev-parse --show-toplevel` from the intended directory
- Re-clone or restore the repo if .git is missing
- Note the DiscoveryFailed arm instead wraps errors with 'git discover failed for <path>' context — this bail is specifically NotARepo
Example fix
// before
gate.check(Path::new("/tmp/scratch")).await?;
// after
gate.check(Path::new("/home/dev/project")).await?; // path inside the repo Defensive patterns
Strategy: validation
Validate before calling
fn gate_precheck(cwd: &Path) -> anyhow::Result<()> {
let out = std::process::Command::new("git").arg("-C").arg(cwd).args(["rev-parse","--show-toplevel"]).output()?;
if !out.status.success() { anyhow::bail!("launch from inside a git repository, not {}", cwd.display()); }
Ok(())
} Type guard
fn has_git_ancestor(p: &Path) -> bool { p.ancestors().any(|a| a.join(".git").exists()) } Try / catch
match gate.enter(cwd).await {
Err(e) if e.to_string().starts_with("not a git repository") => {
eprintln!("switch to your project directory or set workspace path inside the repo");
Err(e)
}
other => other,
} Prevention
- Start sessions from within the repo (or resolve repo root at startup)
- Validate workspace configuration paths point inside a repo
- Watch for moved/deleted repos; re-clone if .git is gone
- Prefer canonicalized paths before gate checks
When it happens
Trigger: Invoking a gated session/workspace operation with a working directory outside any repo; the gate's probe walk reaches the filesystem root without finding .git.
Common situations: Running the tool from a scratch/temp directory; .git deleted or repo moved; passing a drive root or home dir as workspace; wrong cwd set by an IDE/runner.
Related errors
- not a git repository: {}
- unsupported checkout target (need a full commit oid or a sim
- refusing unsafe fetch refspec
- {what} must not be empty
- {what} '{value}' must not start with '-'
AI-assisted analysis of xai-org/grok-build@bc7f02eddd (2026-08-31).
Data as JSON: /api/errors/de2e9f0a9a1fcb38.
Report an issue: GitHub.