Skip to content

fix: allow @ in branch names (valid per git-check-ref-format)#1411

Open
bellalMohamed wants to merge 1 commit into
anthropics:mainfrom
zeal-io:fix/allow-at-branch-names-upstream
Open

fix: allow @ in branch names (valid per git-check-ref-format)#1411
bellalMohamed wants to merge 1 commit into
anthropics:mainfrom
zeal-io:fix/allow-at-branch-names-upstream

Conversation

@bellalMohamed

Copy link
Copy Markdown

Problem

validateBranchName in src/github/operations/branch.ts rejects branch names containing @, even though git check-ref-format permits @ and GitHub itself accepts such branches. When the action runs on a PR whose head or base branch contains an @, validation throws before any git operation and the action fails immediately:

Error: Action failed with error: Invalid branch name: "@hotfix/<ticket>-<description>".
Branch names must start with an alphanumeric character and contain only alphanumeric
characters, forward slashes, hyphens, underscores, periods, hashes (#), plus signs (+),
or commas (,).

This shows up in real workflows: ticket conventions like TICKET-123@add-feature (#998), leading-prefix conventions like @hotfix/... (we run this action org-wide for PR-comment automation on private repos, and every PR from an @-prefixed hotfix branch fails at the prepare step with the error above), and agent tooling that appends @<sessionid> (#1305). There is no workaround other than renaming the branch, which is often not under the user's control.

Fixes #998.

Root cause

The whitelist regex at src/github/operations/branch.ts:68 is:

const validPattern = /^[a-zA-Z0-9][a-zA-Z0-9/_.#+,-]*$/;

@ is not in either character class, so any ref containing one is rejected regardless of position.

The whitelist exists for injection safety, but branch names are never passed through a shell — git calls use execFileSync with an argv array — so @ carries no injection risk under that execution model. This is the same reasoning used to add # in #1167, + in #1248, and , in #1310.

Fix

Add @ to the whitelist, including the leading position: /^[a-zA-Z0-9@][a-zA-Z0-9/_.#+,@-]*$/.

  • The leading-character restriction exists to prevent option injection (-x, --help); @ is not an option prefix, so allowing it first does not weaken that protection. Leading @ is what @hotfix/...-style conventions need, and git check-ref-format --branch "@hotfix/x" accepts it.
  • The bare name @ is rejected with a dedicated check: per git-check-ref-format, a refname cannot be the single character @, and @ resolves to HEAD in git revision syntax, so it must never reach git as a branch argument where it could be interpreted as a revision instead.
  • The @{ reflog sequence is still rejected by the existing dedicated check (untouched).
  • The surrounding comment block, JSDoc, and user-facing error message are updated to match, same as the previous character additions.

Relationship to existing PRs

#999, #1022, and #1305 also propose allowing @. This PR is intended to complement them with three differences: (1) it is based on current main (#1310 landed on the same lines, so the earlier diffs now conflict); (2) it also accepts @ in the leading position, which is the failure mode for @hotfix/...-style conventions; and (3) it adds an explicit bare-@ guard with a test so HEAD shorthand cannot slip through the widened character class. Happy to close this in favor of any of those if a maintainer prefers.

Testing

🤖 Generated with Claude Code

`validateBranchName` rejects branch names containing `@`, even though
`git check-ref-format` permits `@` and GitHub itself accepts such
branches. PRs whose head or base branch contains an `@` fail validation
in-process before any git operation, so the action errors out
immediately.

Branch names with `@` show up in real workflows: ticket conventions
like "TICKET-123@add-feature" (anthropics#998), leading-prefix conventions like
"@hotfix/...", and agent tooling that appends "@<sessionid>" (anthropics#1305).
There is no workaround other than renaming the branch, which is often
not under the user's control.

Branch names are never passed through a shell (git calls use
execFileSync argv arrays), so `@` carries no injection risk. This is
the same reasoning used to add `#` in anthropics#1167, `+` in anthropics#1248, and `,` in
anthropics#1310. The bare name "@" (HEAD shorthand in git revision syntax) and
the "@{" reflog sequence are still rejected.

- Add `@` to the validateBranchName whitelist regex, including the
  leading position (the leading-character rule blocks option injection
  via `-`, which `@` cannot cause)
- Reject the bare name "@" with a dedicated check
- Update the surrounding comment, JSDoc, and error message to match
- Add test cases for @-containing names and bare "@"

Fixes anthropics#998

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Branch name validation rejects @ character which is valid in git

1 participant