vectordotdev/vector · error

propagated git2::Error from branch lookup (no literal…

Error message

propagated git2::Error from branch lookup (no literal message)

What it means

branch_exists looks up a local branch with git2's Repository::find_branch. A NotFound error is translated to `Ok(false)`, but any other git2::Error (e.g. invalid branch name specification, corrupt refs, libgit2 backend failure) is propagated verbatim into an anyhow error via `bail!(e)`, so the surfaced message is libgit2's own — not a custom literal.

Solutions

  1. Fix the branch-name string to a valid git ref name (no spaces, `..`, `~`, `^`, `:`, `?`, `*`, `[`, `\`, control chars, or leading/trailing dots)
  2. Check repo health: `git fsck`, and verify `refs/heads/<branch>` isn't corrupted
  3. Inspect the propagated git2 message for the underlying libgit2 cause and address it (e.g. rebuild refs, re-clone)

Example fix

// before
branch_exists("feature/fix bug")?; // invalid ref name -> git2::Error
// after
branch_exists("feature/fix-bug")?; // Ok(true/false)
Defensive patterns

Strategy: try-catch

Validate before calling

const INVALID_REF_CHARS: &[char] = &[' ', '~', '^', ':', '?', '*', '[', '\\'];
fn valid_branch_name(b: &str) -> bool {
    !b.is_empty() && !b.starts_with('.') && !b.ends_with('.') && !b.contains("..")
        && !b.chars().any(|c| INVALID_REF_CHARS.contains(&c) || c.is_control())
}

Try / catch

match branch_exists(name) {
    Ok(true) => { /* branch exists */ }
    Ok(false) => { /* create it */ }
    Err(e) => {
        // message is the raw git2/libgit2 error; log context alongside it
        eprintln!("branch lookup failed for '{name}': {e:#}");
    }
}

Prevention

When it happens

Trigger: Calling branch_exists (directly or via checkout_or_create_branch) when find_branch fails with a non-NotFound code: malformed branch name (invalid ref characters), a refs database problem, or another libgit2 internal error.

Common situations: Passing a branch name containing invalid ref characters (spaces, `..`, leading/trailing dots); running in a repo with corrupted or packed-refs issues; using names git treats as ambiguous or invalid like `HEAD` misuse.

Understand the failure class

Background: "git command failed": what it means when a tool shells out to git and git exits non-zero — this error's family across 21 libraries.

Related errors


AI-assisted analysis of vectordotdev/vector@0d4ab78a4f (2026-09-16). Data as JSON: /api/errors/228d74822a94b19b. Report an issue: GitHub.

Appendix: source

Thrown at vdev/src/utils/git.rs:208

    Command::new("git").args(["clone", repo_url]).check_output()
}

/// Walks up from the current working directory until it finds a `.git`
/// and opens that repo.  Panics (Err) if none is found.
fn find_repo() -> Result<Repository, git2::Error> {
    Repository::discover(".")
}

pub fn branch_exists(branch: &str) -> Result<bool> {
    let repo = find_repo()?;

    // Do the lookup inside its own scope so the temporary Branch<'_> is dropped
    // before we try to drop `repo` at function exit.
    let exists = {
        match repo.find_branch(branch, BranchType::Local) {
            Ok(_) => true,
            Err(e) if e.code() == ErrorCode::NotFound => false,
            Err(e) => bail!(e),
        }
    };

    Ok(exists)
}

pub fn checkout_branch(branch_name: &str) -> Result<()> {
    let _output = run_and_check_output(&["checkout", branch_name])?;
    Ok(())
}

pub fn checkout_main_branch() -> Result<()> {
    let _output = run_and_check_output(&["switch", MASTER_BRANCH])?;
    Ok(())
}

pub fn create_branch(branch_name: &str) -> Result<()> {
    let repo = find_repo()?;

View on GitHub (pinned to 0d4ab78a4f)