Repository navigation
[Bug]: GIT_BRANCH_NAME naming the current branch fails the mandatory before_specify hook #5003
Description
Bug Description
speckit-git-feature documents GIT_BRANCH_NAME as "use this exact branch name". When that name is the branch already checked out, the script exits 1 with "Branch already exists". The before_specify hook that runs it is mandatory (optional: false), so /speckit-specify reports a hook failure on every run from an existing branch.
The script already handles this case behind --allow-existing-branch (it does nothing when the current branch is the target), but the command template never passes that flag.
Teams that create the branch before writing the spec (from a tracker, with names like feature/PROJ-42-login) hit this every time.
Steps to Reproduce
- Create a project with the git extension and check out a branch:
git init -q p2 cd p2 uvx --from git+https://github.com/github/spec-kit.git@v1.2.1 specify init --here --force --integration claude --script sh --ignore-agent-tools uvx --from git+https://github.com/github/spec-kit.git@v1.2.1 specify extension add git git add -A git commit -qm init git checkout -q -b feature/PROJ-42-login - Run the script the way
.claude/skills/speckit-git-feature/SKILL.mdinvokes it, withGIT_BRANCH_NAMEset to the current branch:GIT_BRANCH_NAME=feature/PROJ-42-login .specify/extensions/git/scripts/bash/create-new-feature-branch.sh --json --short-name login "Login page"
Expected Behavior
Exit 0 and stay on feature/PROJ-42-login. An explicit GIT_BRANCH_NAME that names the current branch is a request to use that branch, not to create a new one.
Actual Behavior
Exit 1 with "Branch already exists". The branch is unchanged, so the error is the only effect. The same call with --allow-existing-branch exits 0 and prints the expected JSON.
Either change would fix it:
- in the script, treat
GIT_BRANCH_NAMEequal to the current branch as a no-op; - or have the command template pass
--allow-existing-branchwhenGIT_BRANCH_NAMEis set.
The first is smaller and also covers direct calls. The PowerShell and Python ports would need the same change.
Specify CLI Version
1.2.1 (git extension 1.0.1). Also present in 0.12.4 with git extension 1.0.0.
AI Agent
Claude Code
Operating System
macOS 26 (Darwin 25.6.0, arm64)
Python Version
Python 3.12.7
Error Logs
$ GIT_BRANCH_NAME=feature/PROJ-42-login .specify/extensions/git/scripts/bash/create-new-feature-branch.sh --json --short-name login "Login page"
Error: Branch 'feature/PROJ-42-login' already exists. Please use a different feature name or specify a different number with --number.
exit=1
branch=feature/PROJ-42-login
$ GIT_BRANCH_NAME=feature/PROJ-42-login .specify/extensions/git/scripts/bash/create-new-feature-branch.sh --json --allow-existing-branch --short-name login "Login page"
{"BRANCH_NAME":"feature/PROJ-42-login","FEATURE_NUM":"feature/PROJ-42-login"}
exit=0Additional Context
#1117 proposed a SPECIFY_USE_CURRENT_BRANCH option and was closed without merge. This report does not ask for a new option. It only asks that the existing GIT_BRANCH_NAME override work when the branch already exists.
AI Disclosure
Investigated and drafted with Claude Code (Claude Opus 5.5, human-supervised). The reproduction was run as written and the log above is its unedited output. I reviewed the report before filing.
Activity
github-actions commentedon Oct 17, 2026
Bug assessment — current-branch-hook: Valid · severity medium
Bug Assessment: GIT_BRANCH_NAME naming the current branch fails the mandatory before_specify hook
Report (summarized)
The reporter (PascalThuet, contributor) reports that with Specify CLI 1.2.1 and git extension 1.0.1, setting
GIT_BRANCH_NAMEto the branch already checked out causes the git feature script to exit 1 withBranch already exists. The script documentsGIT_BRANCH_NAMEas an exact branch-name override, and thebefore_specifyhook is mandatory, so/speckit-specifyfails for projects that pre-create their tracker-named branch. The report includes a reproduction using Bash on macOS and states the same behavior was present in 0.12.4/git extension 1.0.0.The existing
--allow-existing-branchflag makes this case succeed, but the generated command invocation does not pass that flag. No additional comments were present.Symptom
When
GIT_BRANCH_NAMEequals the currently checked-out branch, the branch script attempts to create the already-existing branch and reports an error instead of treating the explicit exact-name request as a no-op. The expected behavior is exit 0, remain on that branch, and emit the normal JSON result so the mandatory hook can continue.Reproduction
feature/PROJ-42-login.create-new-feature-branch.sh --json --short-name login "Login page"withGIT_BRANCH_NAME=feature/PROJ-42-login.Branch 'feature/PROJ-42-login' already existserror.--allow-existing-branch; the report states this exits 0 and emits the expected JSON.The report does not provide an independent reproduction for PowerShell or Python, so cross-platform parity should be verified during remediation.
Suspected Code Paths
extensions/git/scripts/bash/create-new-feature-branch.sh:495-500— assignsGIT_BRANCH_NAMEdirectly toBRANCH_NAME, establishing the exact-name override.extensions/git/scripts/bash/create-new-feature-branch.sh:566-589— attemptsgit checkout -b; when the target exists, it only accepts the current-branch no-op inside theALLOW_EXISTINGbranch, otherwise emits the existing-branch error.extensions/git/scripts/python/create_new_feature_branch.py:492-497— mirrors the exact-name override.extensions/git/scripts/python/create_new_feature_branch.py:564-605— mirrors the Bash create/existing-branch decision and likewise requiresargs.allow_existingfor the current-branch no-op.extensions/git/scripts/powershell/create-new-feature-branch.ps1:445-454and:514-543— implement the same override and existing-branch handling, including the no-op only when-AllowExistingBranchis supplied.extensions/git/commands/speckit.git.feature.md:17-22,58-63— documents thatGIT_BRANCH_NAMEis the exact branch name but the shown Bash and PowerShell invocations do not include the allow-existing flag.extensions/git/extension.yml:43-49— registersspeckit.git.featureas thebefore_specifyhook withoptional: false, making the failure block specification.tests/extensions/git/test_git_extension_python_parity.py:422-444— covers existing branches with and without the flag, but does not cover an override equal to the current branch.Root Cause Hypothesis
Confidence: high. The scripts intentionally special-case an existing target branch only when
--allow-existing-branch/args.allow_existing/-AllowExistingBranchis set.GIT_BRANCH_NAMEchanges branch-name generation but does not imply that the explicit target may already be the current branch. The command documentation forwards the override but not the flag, and the mandatory hook therefore turns this expected pre-created-branch workflow into a failure.Proposed Remediation
Preferred: In all three branch-script implementations, when the exact
GIT_BRANCH_NAMEoverride is set and the resolved current branch equals the requested branch, treat the failedgit checkout -bas a successful no-op. Preserve the current error for a different existing branch unless the explicit allow-existing option is supplied; that avoids silently switching branches and keeps the existing safety behavior. Keep the normal JSON output and persistence hint unchanged.Alternatives:
--allow-existing-branch(and the PowerShell equivalent) wheneverGIT_BRANCH_NAMEis set. This is smaller at the command layer but does not fix direct script callers and may allow switching to a different existing branch, which is broader than the reported requirement.GIT_BRANCH_NAMEimply allow-existing behavior for any existing target. This is simpler but risks silently switching away from the current branch and is not recommended.Files likely to change:
extensions/git/scripts/bash/create-new-feature-branch.shextensions/git/scripts/python/create_new_feature_branch.pyextensions/git/scripts/powershell/create-new-feature-branch.ps1tests/extensions/git/test_git_extension.pytests/extensions/git/test_git_extension_python_parity.pyTests to add or update:
GIT_BRANCH_NAMEto the repository's current branch and assert exit 0, unchanged HEAD, and matching JSON output.Risks & Considerations
/speckit-specifyto continue.Open Questions
GIT_BRANCH_NAMEnaming a different existing branch ever switch automatically, or should only the current-branch no-op be supported?]