linera-io/linera-protocol · error · anyhow

HEAD is not on a branch - it may be detached

Error message

HEAD is not on a branch - it may be detached

What it means

Raised by `GithubContext::get_local_git_info` (linera-summary github.rs) when the tool runs in local mode and the current git repository's HEAD does not point at a branch (git2's `head().is_branch()` is false). A detached HEAD (or any non-branch symbolic ref) has no branch name to report, so the summary context cannot be built. Local mode is a testing path that reads the branch name from the working copy.

Source

Thrown at linera-summary/src/github.rs:97

    }

    /// Returns the repository the PR belongs to.
    pub fn repository(&self) -> &GithubRepository {
        &self.repository
    }

    fn get_local_git_info() -> Result<(String, String, String)> {
        let repo = git2::Repository::open_from_env().context("Failed to open git repository")?;

        let head = repo.head()?;
        let commit_hash = head.peel_to_commit()?.id().to_string();

        let branch_name = if head.is_branch() {
            head.shorthand()
                .ok_or_else(|| anyhow!("Failed to get current branch name"))?
                .to_string()
        } else {
            anyhow::bail!("HEAD is not on a branch - it may be detached");
        };

        // This local mode is only used for testing, so we're just hardcoding `main` as the base branch for now.
        Ok((commit_hash, branch_name, "main".to_string()))
    }

    fn from_env(is_local: bool, pr_number: Option<u64>) -> Result<Self> {
        let env_pr_commit_hash = env::var("GITHUB_PR_COMMIT_HASH");
        let env_pr_branch = env::var("GITHUB_PR_BRANCH");
        let env_base_branch = env::var("GITHUB_BASE_BRANCH");
        let env_pr_number = env::var("GITHUB_PR_NUMBER");

        let (pr_commit_hash, pr_branch, base_branch, pr_number) = if is_local {
            let (commit_hash, branch_name, base) = Self::get_local_git_info()?;
            (
                commit_hash,
                branch_name,
                base,

View on GitHub (pinned to 6c226ddcb3)

Solutions

  1. Attach HEAD to a branch before running: `git checkout -b <branch>` (or `git checkout <existing-branch>`)
  2. In GitHub Actions, configure `actions/checkout` with `ref: <branch>` so HEAD is on a branch
  3. Run in non-local mode instead by setting GITHUB_PR_COMMIT_HASH, GITHUB_PR_BRANCH, GITHUB_BASE_BRANCH and GITHUB_PR_NUMBER

Example fix

# before
git checkout 1a2b3c4   # detached HEAD
linera-summary ...           # -> bail: HEAD is not on a branch

# after
git checkout -b pr-analysis 1a2b3c4
linera-summary ...
Defensive patterns

Strategy: validation

Validate before calling

# Check HEAD is on a branch before running linera-summary in local mode
if ! git symbolic-ref -q HEAD > /dev/null; then
  echo "detached HEAD: create a branch first (git checkout -b <name>)" >&2
  exit 1
fi

Prevention

When it happens

Trigger: Running linera-summary locally with `is_local = true` while HEAD is detached — e.g. after `git checkout <sha>`, an interrupted `git rebase`, or a CI checkout (actions/checkout checks out the PR commit by default, which is detached).

Common situations: Running the PR-summary tool on a CI runner where actions/checkout left HEAD detached; locally testing a specific commit without creating a branch; mid-rebase working copies.

Related errors


AI-assisted analysis of linera-io/linera-protocol@6c226ddcb3 (2026-08-22). Data as JSON: /api/errors/c8939f6c4fc30353. Report an issue: GitHub.