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

Abierto
#1,777 0 comentarios 0 reacciones 0 asignados Ver en GitHub
bug mcp p2
Lenguaje dominante
TypeScript
Estrellas
8.9k
Forks
2.1k
Métricas de merge de PR
Métricas de PR pendientes

Descripción

**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.

Guía de contribución

Abrir la guía de contribución

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.