Workflow code-review burns excessive tokens (1.1M+ for 5 files) and returns empty results

Status Open
Maintainer reply None cached
Activity 4 comments · opened Jul 15, 2026

Problem

The code-review workflow (Workflow({ name: "code-review" })) consistently consumes disproportionate tokens and wall-clock time relative to the work being done, often returning null/empty results.

Reproduction

In a session reviewing 5 changed files (3 Python scripts, 1 YAML config, 1 Markdown skill definition — all small), the workflow:

  • Consumed ~1.1M tokens (went from ~33% of a 4-hour budget to ~75% in minutes)
  • Ran for 18+ minutes before being manually stopped
  • All 4 partial results in the journal were null — zero findings returned

This is the third incident in the same project where the workflow code review went off the rails in the same way.

For comparison, fork-based reviews (/internal-code-reviewer, /internal-test-reviewer) of the same files completed in under 2 minutes, consumed a fraction of the tokens, and returned actionable findings (dead code, variable shadowing, stdout leaks in tests).

Impact

  • Real budget cost: ~40% of a 4-hour session budget burned on a single review that produced nothing
  • The user had remaining implementation work (2+ tasks) that is now budget-constrained
  • The workflow's token consumption is not visible or controllable until after the damage is done

Expected behavior

A code review of 5 small files should not consume more tokens than writing those files did. The workflow should either:

  1. Scale its agent count to the size of the changeset (5 files doesn't need the same fan-out as 50)
  2. Have a token budget cap that prevents runaway consumption
  3. Fail fast if agents are returning empty results rather than continuing to spawn more

Environment

  • Claude Code CLI
  • Model: Opus
  • The code-review workflow is a built-in named workflow, not a custom script

View original on GitHub ↗

4 Comments

jsco2t · 1 month ago

For clarity - I'm not advocating for a refund here. I mostly want to make sure this isn't happening at scale.

kcarriedo · 1 month ago

The 1.1M token / 18-minute / empty result combination on 5 small files is a diagnostic pattern worth naming: the code-review workflow is likely spawning subagents that each receive the full session context, not just the diff they need to review. If the session was already at moderate depth before triggering the review, every spawned subagent inherits that context and each "reviewer" is paying for context that has nothing to do with the 5 files.

A few things worth checking in the transcript (~/.claude/projects/**/*.jsonl) to confirm:

  • Look at the tool_use entries for the code-review workflow invocation. If you see multiple task or agent spawns with async: true, each one is pulling from the same token pool simultaneously.
  • Check the context_used or input_tokens fields on the subagent tool_result entries. If they're large (relative to the 5-file diff), the subagents are receiving more context than they need.

The practical workaround for now: run code-review workflows from a fresh session scoped to just the diff, rather than from inside a long-running session. It trades the convenience of one session for a much lower token floor per review pass.

Longer term this is a subagent context scoping problem - the workflow should be able to declare "reviewers only need the diff and the repo summary, not the full parent context." That would make the workflow usable without the transcript-size caveat.

sergeyandreev-ruby · 23 days ago

Same issue here

CharlesWintersTW · 20 days ago

Independent reproduction with the mechanism identified, plus token accounting that refines @kcarriedo's context-inheritance hypothesis.

Repro: a single-file diff — 28 lines changed (+28/−7) in one C# file, Unity project. Invoked /code-review <PR#> with no explicit level. Manually stopped at ~20 minutes.

Result: 14 agents, ~20 minutes, 1 confirmed finding (a simplification nit). Of the 9 verifier verdicts that completed before I killed it, 6 came back REFUTED.

Root cause — the verify fan-out is uncapped and scales with candidate line numbers, not changeset size. From the persisted workflow script:

  • high = 3 correctness finders + 1 cleanup finder, each asked for up to 6 candidates → up to 30 candidates.
  • Verify spawns one agent per distinct (file, line) location, with no cap on that count. maxFindings: 10 caps the report, not the fan-out.
  • The location-grouping step exists to collapse this, and the script's own comment budgets it at "~40% [collision] at p50". On a small diff collision approaches zero: my 13 candidates landed on lines 2970, 2972, 2975, 2978, 2980, 2988 — adjacent but distinct — producing 9 separate verifier agents that each independently re-read the same file and diff.

So the smaller the diff, the worse the ratio. Four finders fishing for six candidates each inside 28 lines cannot collide.

Token accounting — parsed from the workflow's own agent-*.jsonl transcripts, summed across all 14 agents:

| | tokens |
|---|---|
| output | 118,600 |
| cache_creation | 1,978,219 |
| cache_read | 25,467,587 |
| uncached input | 17,955 |

Two things this shows:

  1. Output is negligible (119k). The spend is almost entirely input, so it is invisible to any output-based intuition about how much work was done.
  2. Per-agent prefix is 106k–240k cache_creation, so each agent does start with a large context floor — directionally what @kcarriedo suggested. But the dominant term is cache_read at 25.5M, and that is driven by turn count, not fan-out alone: three agents ran 91, 73 and 45 assistant turns, contributing 8.1M, 5.5M and 3.0M cache reads respectively. Every turn re-reads the full ~120k+ prefix, and there is no per-agent turn or tool-call budget.

The cost model is fan-out × per-agent context floor × turns. On a 28-line diff, none of the three terms was bounded by the size of the work.

Second finding — the routing trigger is effort level, never changeset size. The workflow's own whenToUse reads: "Launched by the /code-review skill at high, xhigh, or max effort when workflows are enabled." I passed no level, so it inherited "effortLevel": "high" from settings and silently left the session. A user who has always typed low/medium gets inline review for months, then one untyped invocation fans out 14 agents — with no visible difference in how they invoked it. Compounding it, "skipWorkflowUsageWarning": true was present in my settings without my having set it by hand (cf. #78019), so the pre-launch confirmation never appeared.

Suggested fixes, roughly in order of value:

  1. Cap verifier agents outright (min(groups, 6) or similar) — the report is capped at 10 findings anyway.
  2. Scale the perAngle candidate budget by diff size, not by effort level alone.
  3. Gate workflow routing on changeset size as well as level — a sub-50-line single-file diff should not leave the session at any effort.
  4. Add a per-agent turn budget. 91 turns to review a 28-line diff is the largest single multiplier here.

🤖 Generated with Claude Code