File change system-reminders inject full file contents repeatedly, context grows to 692K tokens
TL;DR: Editing lots of files in a long session causes token usage to explode — full file contents get re-injected into context on every turn and never get cleaned up.
Bug
When files are modified during a Claude Code session, <system-reminder> blocks containing full file contents are injected into the conversation context. These reminders persist and accumulate — they are not removed after being acknowledged. In a long session with many file edits, the context window fills with repeated file contents.
Verified data from session transcript
Extracted from the session's .jsonl transcript (usage field on each assistant message):
- Total input tokens processed: 424,620,034 (424M)
- Context size at session end: 692,190 tokens (near the 1M limit)
- Cache read tokens: 402,378,746 (the same content re-read on every turn)
- Output tokens: 248,911
The context grew steadily from ~50K tokens to 692K tokens over 923 messages. The growth is primarily from accumulated system-reminder file change notifications — 17 modified files injecting ~42K tokens of file contents per turn.
Files injected as system-reminders (measured)
| File type | Tokens per injection |
|-----------|---------------------|
| Large markdown file (500 lines) | 14,400 |
| Medium markdown file (320 lines) | 3,605 |
| TypeScript hook (270 lines) | 2,700 |
| TypeScript tool (250 lines) | 2,519 |
| TypeScript tool (240 lines) | 2,374 |
| TypeScript hook (200 lines) | 2,032 |
| Text evidence file (135 lines) | 1,969 |
| Shell script (190 lines) | 1,941 |
| Skill definition (180 lines) | 1,805 |
| Text evidence file (100 lines) | 1,668 |
| Text evidence file (150 lines) | 1,422 |
| TypeScript hook (120 lines) | 1,207 |
| + 5 smaller files | 3,851 |
| Total per turn | ~42,298 |
Reproduction
- Start a Claude Code session
- Use the Edit/Write tool to modify 10+ files (any mix of .ts, .md, .sh, .txt)
- Continue the conversation for 20+ turns
- Check the
.jsonltranscript — observecache_creation_input_tokensandcache_read_input_tokensgrowing with each message - The system-reminder blocks are visible in the conversation as
<system-reminder>Note: {file} was modified...</system-reminder>containing full file contents
Caveat
The token numbers above are verified from the session transcript. However, I cannot confirm that file change notifications are the sole cause of context growth. Other factors may contribute: conversation history, tool call results, compacted context from earlier messages, skills list injections, and other system-reminders. The 42K per-turn estimate is based on measuring the file sizes on disk — I cannot directly measure the injection frequency or confirm it happens on every turn vs selectively.
Suggestion
- File change reminders should be injected once after the modification, then dropped from context
- Or: include only the diff, not the full file
- Or: provide a setting to disable file change notifications for files the model itself modified (it already knows what it wrote)
Environment
- Claude Code 2.1.81
- macOS
- 923-message session, 17 modified files
6 Comments
Found 3 possible duplicate issues:
This issue will be automatically closed as a duplicate in 3 days.
🤖 Generated with Claude Code
Update: I've upgraded to 2.1.92 and ran a baseline test. On a fresh session with no file edits, the first assistant message consumed 20,209 cache_creation tokens — but that appears to be system prompt + tool definitions + skills/memory, not file change notifications.
The original report was about within-session accumulation after file edits. I haven't reproduced that on 2.1.92 yet.
Reproduction prompt for others: Paste this as your first message in a new session to check your baseline, then again after editing 10+ files over 20+ turns:
If "Growth" is significantly larger than expected from your conversation text alone, file change notifications may be accumulating. Please share your results and CC version.
Root cause analysis (traced from the v2.1.88 source leak):
The file change notification pipeline has no cleanup mechanism:
L2Yruns every turn, scanning all files CC has ever read in the session. Any mtime change generates a diff.f47wraps the diff in a<system-reminder>user message withisMeta: true— these are permanent and never pruned.Result: Each unique file modification creates a permanent message in the conversation. Linters, formatters, and auto-save each trigger new notifications.
readFileStategrows monotonically (every file ever read), expanding the scan surface.Suggested fixes (ordered by impact):
isMetafile change messagesStill reproduces on 2.1.92 — the code path is unchanged.
Closing as duplicate of #4464 — same root cause. Posted the source-level analysis there.
Root cause analysis and discussion moved to #4464 — the canonical issue for this bug.
This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.