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
- Attach HEAD to a branch before running: `git checkout -b <branch>` (or `git checkout <existing-branch>`)
- In GitHub Actions, configure `actions/checkout` with `ref: <branch>` so HEAD is on a branch
- 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
- In CI, set `ref:` on actions/checkout so HEAD lands on a branch
- Never run the local-mode summary right after `git checkout <sha>` — create a branch first
- Prefer the env-var mode (GITHUB_PR_COMMIT_HASH / GITHUB_PR_BRANCH / GITHUB_BASE_BRANCH / GITHUB_PR_NUMBER) in automation
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
- Failed to get current branch name
- GITHUB_PR_NUMBER is not a valid number: {pr_string}
- GITHUB_TOKEN is not set! This must be run from within CI
- Failed to resolve binary {name}
- Incorrect version for binary {name}
AI-assisted analysis of linera-io/linera-protocol@6c226ddcb3 (2026-08-22).
Data as JSON: /api/errors/c8939f6c4fc30353.
Report an issue: GitHub.