xai-org/grok-build · error · anyhow::Error

not a git repository: {}

Error message

not a git repository: {}

What it means

find_git_root_from_path() walks up from the given path via discover_git_root(); when the discovery reports NotARepo (no .git found up to the filesystem root), it bails naming the offending path. Callers use it to locate the repo root before worktree creation, resume, cleanup, or subdir offset computation.

Source

Thrown at crates/codegen/xai-grok-workspace/src/session/git.rs:419

    let head_commit = head_ref
        .as_ref()
        .and_then(|h| h.target())
        .map(|oid| oid.to_string());
    let head_branch = head_ref
        .as_ref()
        .and_then(|h| h.shorthand().filter(|s| *s != "HEAD").map(str::to_owned));
    PersistedGitMetadata {
        git_root_dir: Some(git_root.to_string_lossy().to_string()),
        git_remotes: remotes.into_iter().collect(),
        head_commit,
        head_branch,
    }
}
pub fn find_git_root_from_path(path: &Path) -> Result<PathBuf> {
    match discover_git_root(path) {
        GitDiscoveryResult::Found(root) => Ok(root),
        GitDiscoveryResult::NotARepo => {
            anyhow::bail!("not a git repository: {}", path.display())
        }
        GitDiscoveryResult::DiscoveryFailed(e) => Err(e),
    }
}
/// Find the main repo root (not the worktree working directory).
/// For regular repos this is the same as find_git_root_from_path.
/// For worktrees, this returns the parent repo's root.
/// Use this for worktree management operations (create/remove/apply).
pub fn find_main_repo_root_from_path(path: &Path) -> Result<PathBuf> {
    let repo = Repository::discover(path)?;
    repo.commondir()
        .parent()
        .map(|p| p.to_path_buf())
        .ok_or_else(|| anyhow::anyhow!("Invalid git repository: {}", path.display()))
}
pub fn change_type_from_git2_delta(delta: git2::Delta) -> ChangeType {
    match delta {
        git2::Delta::Added => ChangeType::Create,

View on GitHub (pinned to bc7f02eddd)

Solutions

  1. Run `git -C <path> rev-parse --show-toplevel` to confirm the path is inside a repo
  2. Pass the actual repo (or a path under it) instead of a scratch directory
  3. Restore/re-clone the repository if .git was deleted
  4. Fix the configured workspace/session path that points outside the repo

Example fix

// before
let root = find_git_root_from_path(Path::new("/tmp/session-123"))?;
// after
let root = find_git_root_from_path(Path::new("/home/dev/project/src/..."))?; // inside the repo
Defensive patterns

Strategy: validation

Validate before calling

fn ensure_inside_repo(p: &Path) -> anyhow::Result<()> {
    let out = std::process::Command::new("git").arg("-C").arg(p).args(["rev-parse","--show-toplevel"]).output()?;
    if !out.status.success() { anyhow::bail!("{} is not inside a git repository", p.display()); }
    Ok(())
}

Type guard

fn is_git_repo(p: &Path) -> bool { p.ancestors().any(|a| a.join(".git").exists()) }

Try / catch

match find_git_root_from_path(&path) {
    Ok(root) => use_root(root),
    Err(e) if e.to_string().starts_with("not a git repository") => {
        // prompt user to point at the repo or re-clone
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling create_worktree_for_resume, cleanup_worktree_on_failure, resume_local_session_in_worktree, or compute_subdir_offset with a path outside any git repository (e.g. /tmp, a home directory, or a session directory recorded before the repo was moved/deleted).

Common situations: Pointing a resume at a workspace copy without .git; repo deleted or .git removed; passing an absolute path on a different mount that has no repo ancestor; typos in the configured workspace path.

Related errors


AI-assisted analysis of xai-org/grok-build@bc7f02eddd (2026-08-31). Data as JSON: /api/errors/ed8c782fda7aa23b. Report an issue: GitHub.