{"record":{"id":"8a5b4832d128a246","repo":"gitbutlerapp/gitbutler","slug":"remote-head-for-remote-name-is-not-symbolic","errorCode":null,"errorMessage":"Remote HEAD for {remote_name} is not symbolic","messagePattern":"Remote HEAD for (.+?) is not symbolic","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/but-action/src/lib.rs","lineNumber":158,"sourceCode":"fn default_target_setting_if_none(ctx: &Context) -> anyhow::Result<()> {\n    if ctx.project_meta()?.target_ref.is_some() {\n        return Ok(());\n    }\n    // Lets do the equivalent of `git symbolic-ref refs/remotes/origin/HEAD --short` to guess the default target.\n\n    let repo = ctx.repo.get()?;\n    let remote_name = repo\n        .remote_default_name(gix::remote::Direction::Push)\n        .ok_or_else(|| anyhow::anyhow!(\"No push remote set or more than one remote\"))?\n        .to_string();\n\n    let mut head_ref = repo\n        .find_reference(&format!(\"refs/remotes/{remote_name}/HEAD\"))\n        .map_err(|_| anyhow::anyhow!(\"No HEAD reference found for remote {remote_name}\"))?;\n    let target_ref_name = head_ref\n        .target()\n        .try_name()\n        .ok_or_else(|| anyhow::anyhow!(\"Remote HEAD for {remote_name} is not symbolic\"))?\n        .to_owned();\n\n    let head_commit = head_ref.peel_to_commit()?;\n\n    ctx.set_project_meta(ProjectMeta {\n        target_ref: Some(target_ref_name),\n        target_commit_id: Some(head_commit.id),\n        push_remote: None,\n    })?;\n    Ok(())\n}\n\n#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, EnumString, Default)]\n#[serde(rename_all = \"camelCase\")]\npub enum ActionHandler {\n    #[default]\n    HandleChangesSimple,\n}","sourceCodeStart":140,"sourceCodeEnd":176,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/58e5313667b857ef39a730e380af31816a7b1768/crates/but-action/src/lib.rs#L140-L176","documentation":"refs/remotes/<remote>/HEAD must be a symbolic reference pointing at the remote's default branch (e.g. refs/remotes/origin/main). default_target_setting_if_none calls try_name() on the ref's target and throws this error if the ref exists but is not symbolic — i.e. it points directly at an object ID or holds an unexpected target kind — so the default branch name cannot be extracted.","triggerScenarios":"The target of refs/remotes/{remote}/HEAD is not a symbolic name: the ref was written as a direct OID (by a tool or manual refs update), or ref storage returned a non-name target (e.g. a peeled object id).","commonSituations":"Third-party tools or scripts that rewrote remote HEAD as a detached ref; manually edited packed-refs; unusual repos migrated from other systems where HEAD symrefs were flattened.","solutions":["Recreate it as a symbolic ref: `git remote set-head origin --auto` (or `--set` to a branch).","Alternatively update the ref directly: `git symbolic-ref refs/remotes/origin/HEAD refs/remotes/origin/main`.","Configure the GitButler target branch explicitly so the symbolic remote HEAD is not needed."],"exampleFix":"// before: HEAD is detached at an OID\n$ git rev-parse refs/remotes/origin/HEAD\nabc123...\n\n// after\n$ git symbolic-ref refs/remotes/origin/HEAD refs/remotes/origin/main","handlingStrategy":"validation","validationCode":"let is_sym = gix::refs::Reference::lookup(\"refs/remotes/origin/HEAD\", repo)\n    .map(|r| r.target().try_name().is_some())\n    .unwrap_or(false);\nif !is_sym {\n    // repair: git symbolic-ref refs/remotes/origin/HEAD refs/remotes/origin/main\n}","typeGuard":null,"tryCatchPattern":"match default_target_setting_if_none(ctx) {\n    Err(e) if e.to_string().contains(\"is not symbolic\") => {\n        // recreate the symref via git symbolic-ref / git remote set-head, then retry\n    }\n    other => other?,\n}","preventionTips":["Never rewrite refs/remotes/<remote>/HEAD as a detached OID; keep it symbolic.","Use `git remote set-head` rather than manual ref writes to manage remote HEAD.","Audit tooling that edits refs so it preserves symref targets."],"tags":["git-refs","symbolic-ref","target-branch","repo-state"],"backgroundTag":"invalid-argument-value","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"}