anthropics/claude-code-action

Tag-mode prompt documents delete_files with a "files" parameter, but the tool schema declares "paths"

オープン

#1,665 opened on 2026/08/15

 (1 件のコメント) (0 件のリアクション) (0 人の担当者)TypeScript (1,889 件のフォーク)auto 404
buggood first issuemcpp3

Repository metrics

Stars
 (7,889 個のスター)
PR merge metrics
 (平均マージ 18d 20h) (30d で 26 merged PRs)

説明

Summary

The tag-mode prompt tells Claude to call mcp__github_file_ops__delete_files with a files parameter, but the tool's schema declares that parameter as paths. Every first attempt to delete a file under use_commit_signing: true therefore fails schema validation.

The mismatch

Prompt instruction — src/create-prompt/index.ts#L827:

  - mcp__github_file_ops__delete_files: {"files": ["path/to/old.js"], "message": "chore: remove deprecated file"}

Tool schema — src/mcp/github-file-ops-server.ts#L414-L425:

server.tool(
  "delete_files",
  "Delete one or more files from a repository in a single commit",
  {
    paths: z
      .array(z.string())
      .describe(
        'Array of file paths to delete relative to repository root (e.g. ["src/old-file.js", "docs/deprecated.md"])',
      ),
    message: z.string().describe("Commit message"),
  },
  async ({ paths, message }) => {

The handler destructures paths. A call shaped as {"files": [...]} fails zod validation before the handler body executes.

How the inconsistency arose

The sibling tool in the same file genuinely does use files. commit_files declares:

server.tool(
  "commit_files",
  ...
  {
    files: z.array(z.string()).describe(...),
    message: z.string().describe("Commit message"),
  },
  async ({ files, message }) => {

So the two tools take differently named array parameters, and the prompt example for delete_files was written against commit_files' shape. The line immediately above it in the prompt is correct:

  - mcp__github_file_ops__commit_files: {"files": ["path/to/file1.js", "path/to/file2.py"], "message": "feat: add new feature"}

Impact

Scoped to use_commit_signing: true, which is the path where delete_files is allowlisted (src/modes/tag/index.ts#L155-L160). In that configuration:

  • The model follows the instruction it was given, the call is rejected, and a turn is spent on a validation error.
  • Recovery depends on the model inferring the correct parameter name from the error. Not fatal, but it is avoidable latency and token spend on a documented, always-present instruction.

This lives in the block that CLAUDE.md identifies as the most important part of the action:

Prompt construction: ... The prompt includes issue/PR body, comments, diff, and CI status. This is the most important part of the action — it's what Claude sees.

Suggested fix

Change "files" to "paths" in the delete_files example at src/create-prompt/index.ts:827.

The one-word fix is obvious, but the class of bug is worth guarding: the prompt hard-codes JSON examples for MCP tools whose schemas live in a different file, with nothing asserting they agree. I'd suggest pairing the fix with a test that imports the tool schemas and asserts every parameter name appearing in a prompt tool-usage example exists in the corresponding schema. Happy to include that in the PR if it's wanted — or to keep the change to the single word if you'd rather not take on the test.

Environment

  • Repository at d721746d683d812e669ce117cebe55a85fbd9c3e (main)

コントリビューターガイド