Tool-captured screenshots are re-sent every turn and dominate transcript bytes

Status Open
Reported on v2.1.228
Maintainer reply None cached
Activity 1 comment · opened Aug 13, 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?

Screenshots captured by Claude Code's own tools (claude-in-chrome / computer-use) are stored as base64 in the session JSONL and re-sent with the full history on every subsequent turn. An image captured at turn N is therefore paid again at every turn after N. There is no way to strip, cap or downscale them, and nothing surfaces that it is happening.

This is the mechanism already documented in #27869, which was closed by the stale bot as NOT_PLANNED — not fixed, and never refuted technically. It matches the signature of the still-open #24147 (cache-read consuming almost the entire quota; labels bug / has repro / area:cost).

I measured my own transcripts over 7 days — 312 sessions, 506.9 MB total:

  • 171.5 MB (33.8% of all transcript bytes) is base64 image data.
  • In the four heaviest sessions, effectively all of it was captured by the tool, not pasted by me.
  • The most extreme case accumulated 34.4 MB and 42 tool-captured images in a session where I sent exactly ONE message.
  • Sessions in which the tool took no screenshots stayed at 2-4 MB.

Same account, same week, same machine. The only variable is whether the tool chose to screenshot.

The failure is silent: no error, no warning, and neither /context nor /usage breaks out image bytes, so there is no way to notice while it accumulates.

What Should Happen?

Images captured by tools should not be silently re-sent in full on every subsequent turn for the rest of the session. Any one of these would resolve it:

  1. Drop or downscale tool-captured images from replayed history once they have been acted on — keep only the most recent N.
  2. A setting to cap image bytes per session, or to disable image return from tool results entirely (e.g. maxImageBytes, or an option to have screenshot tools return text descriptions).
  3. At minimum, make it visible: break out image bytes in /context and /usage, so the cost can be seen while it accumulates rather than after the limit is reached.

Today none of these exist. A user has no mechanism to prevent it and no signal that it is happening.

Error Messages/Logs

Steps to Reproduce

  1. Start a session and give Claude a task that requires inspecting web pages or a UI, so it uses a screenshot-capable tool (claude-in-chrome or computer-use).
  2. Let the session run for 15+ turns while the tool takes screenshots as part of its normal loop.
  3. Run the script below against ~/.claude/projects/**/*.jsonl. It only reads local transcripts.
import glob, json, os

for f in glob.glob(os.path.expanduser("~/.claude/projects/*/*.jsonl")):
    total = os.path.getsize(f)
    if total < 5_000_000:
        continue
    img = 0
    with open(f, encoding="utf-8", errors="replace") as fh:
        for line in fh:
            try:
                d = json.loads(line)
            except Exception:
                continue
            c = (d.get("message") or {}).get("content")
            if not isinstance(c, list):
                continue
            stack = list(c)
            while stack:
                b = stack.pop()
                if not isinstance(b, dict):
                    continue
                if b.get("type") == "tool_result" and isinstance(b.get("content"), list):
                    stack.extend(b["content"])
                    continue
                if b.get("type") == "image":
                    img += len(((b.get("source") or {}).get("data") or ""))
    print(f"{os.path.basename(f)[:8]}  {total/1e6:6.1f} MB  image {img/1e6:6.1f} MB  ({img/total*100:.0f}%)")
  1. Compare the image fraction against sessions where no screenshot tool was used.

Expected on an affected machine: sessions using screenshot tools sit at 33-45% image bytes; sessions without them sit near 0%. On mine the week-wide figure was 33.8% across 312 sessions.

Claude Model

None

Is this a regression?

I don't know

Last Working Version

2.1.228 more or less

Claude Code Version

2.1.231 (Claude Code)

Platform

Other

Operating System

macOS

Terminal/Shell

Other

Additional Information

Per-session measurement (session IDs + UTC windows)

Support asked in #66815 for session IDs, UTC timestamps and errors so the team can verify server logs. Here is that data for the five heaviest sessions of the week:

| session id (prefix) | MB | image % | captured by TOOL | pasted by me | images | my messages | UTC window |
|---|---:|---:|---:|---:|---:|---:|---|
| 5d14db9a | 55.5 | 39% | 21.6 MB | 0.0 MB | 80 | 6 | 2026-08-12T13:08:27 → 2026-08-13T03:38:39 |
| 6b08a2ba | 47.3 | 40% | 14.7 MB | 4.2 MB | 95 | 15 | 2026-08-09T17:52:38 → 2026-08-10T13:07:59 |
| 3b99ad24 | 45.5 | 33% | 13.5 MB | 1.7 MB | 99 | 17 | 2026-08-10T13:09:03 → 2026-08-11T01:36:47 |
| ed372af6 | 34.4 | 45% | 15.5 MB | 0.0 MB | 42 | 1 | 2026-08-11T15:28:08 → 2026-08-12T01:49:47 |
| 9307400f | 13.9 | 71% | 0.2 MB | 9.8 MB | 37 | 25 | 2026-08-11T16:15:57 → 2026-08-11T20:20:39 |

Control — same week, same machine, sessions where no screenshot tool ran:

| session id (prefix) | MB | image % |
|---|---:|---:|
| d68a3c0a | 2.3 | 0.0% |
| 2eceb8e7 | 3.9 | 0.0% |

Note 9307400f is included deliberately as the counter-example: it is 71% image, but 9.8 of its 9.5 MB were pasted by me. That one is normal usage, not a defect. The pattern that supports this report is the other four, where the tool captured everything.

Full session UUIDs available on request — I did not want to paste full identifiers into a public issue.

Why this matters beyond context bloat

The official docs state: "Claude Code re-reads that history at the cached token rate, so a one-line question in a session that has been open all day still draws usage for the whole conversation." (code.claude.com/docs/en/costs)

Combined with the above, a screenshot taken early in a long session is repaid on every later turn. #27869 measured this at ~13x overhead — 18 screenshots consuming 17% of a Max plan's 5-hour limit across 5 trivial turns.

Request

I hit my weekly limit largely through this mechanism and I would like to ask for a reset of the weekly limit on this account, along the lines of the goodwill token restoration that support described in #66815. I understand this is discretionary and is a separate question from whether the underlying behaviour is fixed — the fix is what this issue is actually about.

Happy to provide full session identifiers, the raw measurement output, or run any diagnostic you'd like through a private channel.

Environment note

macOS, Claude Code 2.1.231, claude.ai subscription (not API). Both claude-in-chrome and computer-use MCP servers were connected during the affected sessions.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗