{"record":{"id":"5461ed7bafd7c261","repo":"gitbutlerapp/gitbutler","slug":"head-does-not-point-to-a-local-branch","errorCode":null,"errorMessage":"HEAD does not point to a local branch","messagePattern":"HEAD does not point to a local branch","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/but-agentlog/src/environment.rs","lineNumber":389,"sourceCode":"        Err(error) => match current_branch_targets(repo) {\n            Ok(fallback) if !fallback.is_empty() => Ok(WorkspaceObservation {\n                stacks: Vec::new(),\n                observed_targets: fallback,\n                error_kind: Some(SnapshotErrorKind::Workspace),\n            }),\n            _ => Err(error),\n        },\n    }\n}\n\nfn current_branch_targets(repo: &gix::Repository) -> anyhow::Result<ObservedTargets> {\n    let head = repo.head()?;\n    let Some(ref_name) = head.referent_name() else {\n        anyhow::bail!(\"HEAD is detached\");\n    };\n    let full_ref_name = ref_name.to_string();\n    if !full_ref_name.starts_with(\"refs/heads/\") {\n        anyhow::bail!(\"HEAD does not point to a local branch\");\n    }\n    if is_workspace_ref_name(ref_name) {\n        anyhow::bail!(\"HEAD points to the GitButler workspace branch\");\n    }\n    let branch = BranchTarget {\n        key: format!(\"ref:{full_ref_name}\"),\n        name: ref_name.shorten().to_string(),\n    };\n    // Derive the PR association from the forge review cache rather than stored\n    // metadata. Synthesize a metadata entry carrying the resolved number so a\n    // branch with a cached PR is reported even without stored branch metadata.\n    let reviews = match resolve_branch_pr(repo, ref_name, &forge_prs_by_head(repo)) {\n        Some(pull_request) => {\n            let mut metadata = Branch::default();\n            metadata.review.pull_request = Some(pull_request);\n            review_targets(&branch.key, Some(&metadata))\n        }\n        None => Vec::new(),","sourceCodeStart":371,"sourceCodeEnd":407,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/58e5313667b857ef39a730e380af31816a7b1768/crates/but-agentlog/src/environment.rs#L371-L407","documentation":"current_branch_targets in crates/but-agentlog/src/environment.rs requires HEAD to point to a local branch (refs/heads/...). If HEAD's referent is any other ref (e.g. refs/remotes/... or a custom ref), it bails with \"HEAD does not point to a local branch\". It also separately rejects the GitButler workspace ref.","triggerScenarios":"Calling current_branch_targets while HEAD is attached to a remote-tracking ref or non-branch ref (e.g. `git checkout origin/main` detached-attach states, custom symrefs), or to the GitButler workspace ref (which raises a different bail in the same function).","commonSituations":"Tooling that checked out a remote ref or tag-like ref; automation that re-points HEAD at custom refs; running agentlog inside a repo managed by GitButler's workspace mode with HEAD on the workspace ref.","solutions":["Attach HEAD to a local branch: `git switch <local-branch>` so the referent is refs/heads/<branch>.","Create a local branch tracking the remote: `git switch -c <branch> --track origin/<branch>`.","If GitButler workspace mode is active, pause/exit it or run the snapshot against a non-workspace branch."],"exampleFix":"// before\ngit checkout origin/main   # HEAD on refs/remotes/...\n// after\ngit switch -c main --track origin/main","handlingStrategy":"validation","validationCode":"ref=$(git symbolic-ref -q HEAD) && case \"$ref\" in refs/heads/*) ;; *) echo \"HEAD not on a local branch\"; exit 1 ;; esac","typeGuard":null,"tryCatchPattern":"match result {\n    Err(e) if e.to_string().contains(\"HEAD does not point to a local branch\") => {\n        // attach to a local branch and retry\n    }\n    r => r?,\n}","preventionTips":["Checkout remote refs with --track to create a local branch.","Avoid symref tricks that point HEAD at refs/remotes or custom namespaces.","Exit GitButler workspace mode or pick a non-workspace branch before branch-target snapshots."],"tags":["git","refs","rust","branch"],"backgroundTag":"invalid-state-transition","analyzedSha":"58e5313667b857ef39a730e380af31816a7b1768","analyzedAt":"2026-09-18T06:50:32.052Z","contentChangedAt":"2026-09-18T06:50:32.052Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}