anthropics / anthropics/claude-code-action
commit_files/delete_files fail under use_commit_signing when the branch name contains `#`: git ref URLs are built without percent-encoding
- Vorherrschende Sprache
- TypeScript
- Sterne
- 8.9k
- Forks
- 2.1k
- PR-Merge-Kennzahlen
- PR-Kennzahlen ausstehend
Beschreibung
**Type:** bug
**Severity:** medium (commit signing is unusable on affected branches)
**Area:** `src/mcp/github-file-ops-server.ts`, `src/mcp/update-git-reference.ts`
**Effort:** small
## Summary
`validateBranchName` explicitly allows `#` in branch names (`src/github/operations/branch.ts`, added in #1167: "valid per git-check-ref-format and commonly used in branch names like `fix/#123-description`"). The file ops MCP server and `updateGitReference` then interpolate the branch, base branch and default branch **raw** into `fetch()` URLs:
```ts
// src/mcp/github-file-ops-server.ts (getOrCreateBranchRef)
const refUrl = `${GITHUB_API_URL}/repos/${owner}/${repo}/git/refs/heads/${branch}`; // line 69
const baseRefUrl = `${GITHUB_API_URL}/repos/${owner}/${repo}/git/refs/heads/${baseBranch}`; // line 90
const defaultRefUrl = `${GITHUB_API_URL}/repos/${owner}/${repo}/git/refs/heads/${defaultBranch}`; // line 122
// src/mcp/update-git-reference.ts
const updateRefUrl = `${GITHUB_API_URL}/repos/${owner}/${repo}/git/refs/heads/${branch}`; // line 47
```
In a URL, `#` starts the fragment, which is never sent on the wire. For `fix/#123-description` GitHub receives `GET /repos/o/r/git/refs/heads/fix/`.
## Reproduction
Run the action with `use_commit_signing: true` on a PR whose head branch is `fix/#123-description` and let Claude call `commit_files` (or `delete_files`). Driving the real server over stdio against a fake API that mimics GitHub's documented prefix-match behaviour for `git/refs/heads/` (verified read-only: `gh api repos/anthropics/claude-code-action/git/refs/heads/ma` returns an array):
```
BRANCH_NAME env : fix/#123-description
requests received : [ "GET /repos/o/r/git/refs/heads/fix/" ]
expected first request: GET /repos/o/r/git/refs/heads/fix/%23123-description
tool isError : true
tool text : Error: undefined is not an object (evaluating '(await refResponse.json()).object.sha')
```
If no sibling `fix/*` branch exists GitHub returns 404 instead; the server then tries to *create* `refs/heads/fix/#123-description` and gets 422 "Reference already exists". Either way the tool cannot commit. `BASE_BRANCH` containing `#` (line 90) is the same shape as the default branch reported in #1314.
## Expected
The request is sent as `GET /repos/o/r/git/refs/heads/fix/%23123-description`, the ref resolves, and the commit is created.
## Root cause
String interpolation into `fetch()` URLs. The octokit call sites elsewhere are unaffected because octokit percent-encodes template parameters. `encodeBranchNameForUrl` in `src/github/operations/comments/common.ts` already implements the right per-segment encoding (it was applied to the **link** URLs in #1713), but not to these four API URLs. PR #1326 targeted the same sites in 2026-05 but bundled unrelated changes and was closed without landing.
Beitragsleitfaden
Bewertung
Dieses Issue wurde noch nicht bewertet.