[BUG] /code-review --comment silently degrades to terminal printing when the forked agent lacks t he posting tools (repro on 2.1.237, after #84093 closed)

Status Open
Reported on v2.1.233
Maintainer reply None cached
Activity 3 comments · opened Aug 20, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

/code-review <level> <pr-number> --comment is documented to post each finding as an inline comment on the PR's diff. In my run it printed the findings to the terminal instead, posted nothing to GitHub, and raised no error. The parent session's own explanation, verbatim:

In this session the forked agent had neither ReportFindings nor the GitHub inline-comment tool available to it, so it fell back to printing. The transport was missing, not the feature. Notably I do have ReportFindings in this session while the subagent did not.

So the flag's behaviour depends on which tools reach the forked review agent, and when the transport is missing it degrades silently: the run completes, the findings look delivered, and nothing is on the PR. Anything downstream that trusts the flag - a human who walks away expecting review threads, or an agent workflow that gates a merge on the posted record - discovers the gap only by independently re-querying the PR.

This is the same tool-absence class as #84093, which was closed COMPLETED after a maintainer could not reproduce on 2.1.233. I hit it on 2.1.237, through the --comment path. It is distinct from #84474, which is about the workflow-backed review posting through the GitHub MCP server and reporting success; here the forked agent had no posting transport at all and said so.

What Should Happen?

Either of these, and ideally both:

  1. The forked review agent always receives the tools the invocation's flags require - ReportFindings, and whatever --comment posts throug

h.

  1. When the transport is missing, the run fails loudly instead of degrading: a clear "could not post inline comments: tool X unavailable" in

the result, not a normal-looking finding list in the terminal.

Error Messages/Logs

Steps to Reproduce

  1. Interactive session in a repo with an open PR (mine: a solo-maintainer repo, PR with an 8-finding diff).
  2. Run /code-review high <pr-number> --comment.
  3. The review runs and reports 8 findings with file:line pointers - in the terminal only.
  4. gh api repos/<owner>/<repo>/pulls/<pr-number>/comments returns []: nothing was posted, no error was raised.

Claude Model

Opus

Is this a regression?

I don't know

Last Working Version

_No response_

Claude Code Version

2.1.237 (Claude Code)

Platform

Other

Operating System

Other Linux

Terminal/Shell

Other

Additional Information

  • Platform: Linux (openSUSE Tumbleweed)
  • Version: 2.1.237
  • Interactive Ghostty terminal session (not -p, not claude-code-action)
  • The exact command I typed: /code-review high 78 --comment

View original on GitHub ↗

3 Comments

izkreny · 8 days ago
🤖 Written by AI --- read/modified by izkreny! 🤓

Follow-up runs since I filed this, on 2.1.238 and 2.1.239. The short version: the tool absence is still there on 2.1.239, but the silent data loss is intermittent, because whether findings reach the PR depends on the agent improvising a fallback. That splits this report into two claims of different strength, and I think only one of them is really about --comment.

The three runs

| Version | PR | Findings | ReportFindings / inline-comment tool | Landed on the PR? |
|---|---|---|---|---|
| 2.1.237 | groupifico#78 | 8 | agent reported both absent | No. Terminal only, no error |
| 2.1.238 | groupifico#82 | 8 | not established — see the correction below | Yes, all 8 |
| 2.1.239 | groupifico#146 | 2 | agent reported both absent | Yes, both — via gh api |

On 2.1.239 the forked agent said so itself, unprompted, in its result: that neither ReportFindings nor the inline-comment MCP tool was available to it, so it used gh api instead. The findings landed at the right file and line, and the workaround was disclosed rather than hidden.

Evidence from the 2.1.239 transcript

Not the agent's self-report this time. Its own transcript, at ~/.claude/projects/<project>/<session>/subagents/agent-<id>.jsonl, records the whole exchange.

1. The skill instructs the agent to use the tool:

When you are done, submit at most 15 findings via the ReportFindings tool, filling its fields as defined

2. The agent requests both tools by exact name, as deferred tools:

{"name":"ToolSearch","input":{"query":"select:ReportFindings,mcp__github_inline_comment__create_inline_comment","max_results":5}}

3. The harness answers that neither exists:

{"tool_use_id":"toolu_01AJaDHNbNKceCU7Ko9PnxQc","content":"No matching deferred tools found"}

That same record carries "version":"2.1.239".

4. The agent then works around it, which is where the earlier "so I'll post via gh api" line comes from. Across the entire run the tool invocations were Bash ×22, Write ×2, ToolSearch ×2. ReportFindings was never invoked, because it was never available to invoke.

So this is not a case of the tool failing, being mis-called, or timing out. The agent asked the harness for the exact tool its own instructions name, and the harness said it does not exist. On 2.1.239.

A correction to my own reasoning, before anyone leans on it

I had drafted a "does not reproduce on 2.1.238" comment and did not post it. Good, because its central inference was wrong. It concluded "the transport was present and used" from the fact that all 8 findings appeared on the PR.

That inference does not hold. The 2.1.239 run posted its findings with the transport absent, by shelling out to gh api. So a successful --comment run is not evidence that the tools were provisioned, and the 2.1.238 row above has to stay unknown rather than be counted as a clean version. I never verified the tool list on that run, only the outcome.

What I think this means for the report

Ask 1 — always give the forked agent the tools its flags require — is unaddressed and is the durable fix. The absence reproduces two versions on from the original, and it is the actual defect. Everything else is downstream of it.

Ask 2 — fail loudly instead of degrading — matters more than I realised, not less. I had assumed a fix would either provision the tools or make their absence loud. There is a third behaviour in the wild: the agent notices the gap and routes around it. That is the best outcome of the three, but it is a model improvising, not a guarantee, and it is exactly why the silent path must be closed. The same conditions produced total data loss on 2.1.237 and a clean result on 2.1.239, and nothing in the output of a successful run tells you which of those you were one coin-flip away from.

So: please don't close this on a non-reproduction of the symptom. The symptom is intermittent by nature. The provisioning gap underneath it is what to test for, and it is still present.

One fix the report itself needs

Step 4 of my repro has a false-positive path, and I walked into it myself on the 2.1.238 run. GET /pulls/{n}/comments pages at 30. That PR already carried 28 inline comments from an unrelated discussion, so the unpaginated read returned 30 rows and showed only 2 of the 8 findings — indistinguishable from this bug. gh api --paginate showed all 8.

Anyone verifying this on a PR that already has inline discussion should paginate, or they will confirm the bug when it did not happen. Worth knowing if #84093 or #84474 were ever checked that way. The 2.1.239 run had zero prior inline comments, so it was not exposed to this.

Environment

  • Platform: Linux (openSUSE Tumbleweed), interactive terminal, not -p and not claude-code-action
  • Versions: 2.1.237 (original), 2.1.238, 2.1.239 (latest run)
  • Model: Opus 5
  • Public repo in every run, so the PRs above are readable

If you inspect PR #146

The two finding comments have been edited since they were posted: I prefixed each with an AI-authorship disclaimer line and an RF{n} id, because the tool posts under my account with no marker of its own and I want agent-written prose on my PRs labelled as such. The analysis's text below those added lines is untouched. Flagging it so the added lines are not read as something the tool emitted.

secsaba · 4 days ago

Corroborating this on 2.1.246, through the plain /code-review path — no --comment, no PR target, no flags. So the tool-absence half of this is not specific to the posting transport, and it has survived from 2.1.237 to 2.1.246.

I reached your quoted observation independently before finding this issue, which is why I'm adding to it rather than filing again.

What happened

/code-review against main now in a local git repo. The skill forked a sidechain agent whose own prompt instructs it:

When you are done, submit at most 15 findings via the ReportFindings tool, filling its fields as defined [...]

The forked agent could not resolve the tool — not in its loaded schema, and not in its deferred registry:

tool_use:    ToolSearch {"query": "select:ReportFindings", "max_results": 3}
tool_result: "No matching deferred tools found"

tool_use:    ToolSearch {"query": "report findings code review", "max_results": 5}
tool_use:    ToolSearch {"query": "+findings submit review comments", "max_results": 5}
tool_result: "No matching deferred tools found"

It then said so in its final report and fell back to prose:

The ReportFindings tool is not available in this environment (not in the loaded schema, and ToolSearch finds no such deferred tool), so the findings are stated here directly.

Meanwhile the parent session had ReportFindings in its eagerly-loaded schema at that same moment — same session, same process. Same asymmetry you quoted.

The review itself was fine: it read the diff, verified findings, and reported two real ones. Nothing was lost here only because the skill prompt carries a fallback — "also restate the findings in your final reply [...] so they stay visible in sessions that do not render tool output". What is lost is the structured output the host UI renders, and anything keyed off it.

Ruled out locally

Different machine from the original report, and none of the usual suspects apply:

  • No allowedTools, disallowedTools, or disableTools in ~/.claude/settings.json or the project's .claude/settings.local.json
  • No ~/.claude/agents/ and no <project>/.claude/agents/ — no custom agent definition narrowing the set
  • No enabled plugin supplies the agent; the fork ran the built-in skill's own prompt
  • macOS (Darwin 25.5.0), Opus 5, interactive session

Evidence is in the sidechain transcript at ~/.claude/projects/<project>/<session-id>/subagents/agent-<agent-id>.jsonl — the ToolSearch calls and their results are recorded verbatim.

Possible mechanism — cf. #84125

#84125 reports the same shape for a different tool: present in the parent, absent from every subagent's tool set and its deferred registry, in interactive sessions, while the same dispatch under claude -p does receive it. If that pruning is what's biting here too, then this issue and #84125 are one bug with two symptoms, and the --comment degradation is a third.

That's testable: run the same /code-review under claude -p and see whether the forked agent gets ReportFindings. Happy to run it and report back if it would help.

Suggestion

Whatever the mechanism, the forked review agent's prompt should not instruct it to call a tool the fork isn't granted. Either grant it, or make the prompt conditional on what the fork actually has — right now the instruction and the tool set disagree, and only the skill's prose fallback keeps the run usable.

secsaba · 4 days ago

Ran the claude -p test I offered above. It confirms the #84125 mechanism: this is interactive-only tool pruning, not anything specific to /code-review.

Same machine, same repo, same version (2.1.246), same skill, same fork. The only variable is session mode.

Interactive — fork cannot resolve the tool

tool_use:    ToolSearch {"query": "select:ReportFindings", "max_results": 3}
tool_result: "No matching deferred tools found"

Two further keyword queries, same result. The agent fell back to prose and said the tool was unavailable.

Headless (claude -p "/code-review HEAD~1") — fork has it in its loaded schema

tool_use:    ReportFindings {"findings": [], "level": "medium"}
tool_result: "No findings reported."          is_error: false

No ToolSearch call at all — the fork never needed to look, because ReportFindings was already in its tool set. Its full tool list for the run was ['Bash', 'ReportFindings'].

What this means

The tool is granted to the forked review agent under -p and withheld from it in an interactive session, on the same build. That is exactly the asymmetry #84125 describes for LSP:

the LSP tool is absent from every dispatched subagent's active tool set and from its deferred-tool registry [...] The same dispatch under claude -p (headless) does give the subagent LSP, in all six --permission-mode values.

So #84125 is very likely not an LSP bug but a general subagent tool-pruning bug in interactive sessions, and this issue is a second symptom of it — with the --comment degradation in the original report as a third. Worth linking the two rather than fixing them separately.

The forked prompt telling the agent to call a tool the fork isn't granted is still worth fixing on its own, since that's what turns the pruning into a silent degradation rather than a clear error.

Reproduction is two commands in any git repo with a commit to review, comparing the subagents/*.jsonl transcripts of each:

# interactive: type  /code-review HEAD~1
claude -p "/code-review HEAD~1"