[MODEL] Claude verbose code comments by default — ignores instructions to stop.
Preflight Checklist
- [x] I have searched existing issues for similar behavior reports
- [x] This report does NOT contain sensitive information (API keys, passwords, etc.)
Type of Behavior Issue
Persistent bad behavior. Claude ignores my instructions or configuration.
What You Asked Claude to Do
Description
Claude Code adds far too many code comments by default. The comments are mostly redundant, restating what the adjacent code already makes obvious or simply making references to the chat with Claude itself, leaking its chain of thoughts. It happens on every language, every model.
Crucially, this default persists even when explicitly told to stop:
- A clear, mandatory rule in
CLAUDE.mddoes not reliably suppress it. - Reinforcing the rule via the memory system does not stop it either.
I suppose the core problem is that verbose commenting is the out-of-the-box default, and that default is strong enough to override explicit user instructions. Users shouldn't have to stack a CLAUDE.md rule + memory entries + enforcement hooks just to get clean code, and that still working partially.
Environment
- Claude Code
- Model: claude-opus-4-8, also verified on Opus 5 and Sonnet 5.
What Claude Actually Did
Contant verbose code commenting.
Expected Behavior
Restrained commenting as the default — comment only genuinely non-obvious constraints or "why" decisions, not self-evident "what." And when a project instruction says to minimize comments, that instruction should be reliably respected.
Actual behavior
Reflexive explanatory comments on most code output, even when instructed otherwise. Requires constant manual cleanup or cleanup sessions with other models.
Files Affected
all
Permission Mode
Accept Edits was ON (auto-accepting changes)
Can You Reproduce This?
Yes, every time. Happens pretty much on every session.
Steps to Reproduce
Just ask it to write code
Claude Model
Opus, Sonnet, Fable
Relevant Conversation
Some comment examples:
// A contribution ID collided with one owned by someone else, or a channel kind that doesn't match it.
// Must stay below CHUNK_WORDS — the loop steps by the difference.
// Ollama answers empty text with 200 and no vector, which would read as a model fault.
// Unwrapped this is a bare "fetch failed" — no URL, no reason. The usual cause is a container pointing at 127.0.0.1 instead of host.docker.internal.
// Another service on that port answers 200 with HTML, and a raw parse error names neither it nor the URL.
// Asked, never assumed — no path may fall back to the column default.
Impact
High - Significant unwanted changes.
Claude Code Version
2.1.228
Platform
Anthropic API
Additional Context
_No response_
41 Comments
Found 3 possible duplicate issues:
This issue will be automatically closed as a duplicate in 3 days.
🤖 Generated with Claude Code
keep it until it is solved 💃
totally agree! Comments re very verbose and mostly non even human readable
Agreed this is a large usability issue currently. I have to tell it to stop over commenting every time, and it still gets it wrong despite it having this in the CLAUDE.md file and memory more than once.
Comments should only exist for complex parts of the code which aren't understandable without the comment, not to explain every little line of code or every file
Sometimes I still see code between the comments. They should rename the product.
Same here, tried many different approaches to getting the comments down (rules, hooks, instructions) but none seem to be effective. It also got worse in the last few model versions (since Opus 4.7 it really increased).
In some cases, I quite like it though: as a reviewer the comments sometimes help to understand certain things a little bit faster. I go over all the comments, clean them up manually, then approve and merge.
But I don't want this for every task. Some kind of built-in slider / setting per session would be nice to have (defaulting to low comments), or just Claude adhiring to CLAUDE.md instructions.
OMG this is annoying.
The primary issue is that the code comments make references to the chat with claude itself, which should not be persistent in the codebase and are confusing to anyone else reading it who was not part of that same chat.
Code comments should just describe its current state. I don't see why it should every write something like "removed X because of Y ..."
Another annoying this is all the references to "phases" when using the plan mode in code comments. These comments never make sense after completion of the implementation since they reference a chat the user might not have access too and merely describe intermediary implementation steps.
Sometimes the agent needs to change multiple files just to keep comments up-to-date, this is really counter-productive.
Comments should describe the current state of the code, if it is not clear, and eventually reference meaningful documentation Specs/ADRs etc. So the agent knows where to look to find the right context.
To me, comments are just a tiny piece of the problem. EVERYTHING Claude ever says is way, way too verbose (not _just_ code comments). Short of using Caveman, there appears to be nothing anyone can do to fix that.
I get that Anthropic wants the smartest Claude possible, one that can hit every benchmark: I truly get it. But in only training for "intelligence", you've made an asshole AI that won't shut up.
Real users (read any online forum where people discuss Claude: Reddit, Hacker News, Slashdot, etc. ... they will all agree) would _happily_ trade a few benchmark points in exchange for an AI that told you a two sentence answer in two sentences ... instead of two paragraphs.
Commenting so this doesn't get closed
It's a VERY annoying issue we also have. I have to do "comment review" passes to remove most of them
I have instructions in CLAUDE.MD, in skills and in memory. Opus mostly ignores these instructions.
We have been stricken with these excessive comments recently too. Bump this higher.
Hey Claude, next time can I have some code with my comments, thanks?
Commenting so this doesn't get closed.
I tracked LOC and comments per PR and roughly 17% diff is just comments before I ask to condense it during review.
Parsed 464 local session transcripts plus git history. Wanted to add a couple major findings that I have.
It scales with session depth. Comment density of code written, bucketed by how many tool calls had already run in that session:
| tool calls so far | lines written | comment % | blocks >=8 lines per 1k code |
|---|---|---|---|
| 11-30 | 4,175 | 12.1% | 0.82 |
| 31-80 | 16,966 | 13.9% | 2.12 |
| 81-200 | 14,310 | 16.3% | 3.01 |
| 200+ | 16,005 | 15.2% | 4.20 |
It's session findings, not documentation. Among comment blocks of 8+ lines, the share containing an internal issue ID went 8% → 33%. Content is typically a dated investigation result or the narrative of a past regression: commit-message material written into the nearest source file. Same default #85130 asks to change.
And it accretes. Of 255 blocks of 8+ lines in the tree, 121 (47%) were built across more than one commit. One 38-line block was assembled over 14 commits. Nothing ever removes a paragraph.
A/B, same model, same edit task, three fixtures differing only in context:
| fixture | comment lines added |
|---|---|
| terse file, bare instruction | 0 |
| terse file, prompt loaded with rationale (past regression, dates, IDs) | 0 |
| identical code with a 16-line comment block above it | +3 |
Being told rationale did nothing. A verbose neighbour did it. That points at the "match the surrounding comment density" instruction, which has no length bound, so touched regions ratchet up and hold. Cold greenfield prompts stayed terse (Opus 5: 3 comment lines in 30), so this isn't an unconditional default.
With the introduction of watermarking, I doubt this behaviour will be fixed. More comments will increase the effectiveness of watermarking on Claude generated code.
Same issue, Claude writes super long comment blocks with very little code. The comments are based on input, changes but they are over-detailed. If Claude needs this, it should outsource most of the comment info into meta files.
Thiiis! So annoying. I created a custom clean-comments command that I need to run after finishing every new feature.
so annoying, I have to remind it everytime to have less comments and even add in memory but still
Up, particularly annoying issue
Thanks for this research.
I like to add a rule in CLAUDE.md to prepend a prefix tag
CLAUDENOTE:to temporary comments 'for later stripping' (I let the model choose when to strip the comments). I also have a hard limit of 4 lines for permanent non-doc comments (i.e. simple code comments), usually I'll have some kind of exception (for e.g. math-heavy comments, or maybe every 500 lines).The bigger problem I have is the model writing weird poetry instead of human readable prose. I don't know if this is caused by those rules, by Claude.MD compaction (which is what the model claimed to me, CLAUDE.md is the 'house style' and letting the LLM compact it via strange sentence forms propagated the style elsewhere over time).
If this happens to you:
Note: auditing comments on entire codebases can be quite expensive. You can do this quickly with ultracode but expect it to use a lot of tokens (I think for a ~200k lines codebase it used 14 million tokens to check all the comments).
We're also experiencing the same. Excessive comments being added next to the code, references to the chat itself, etc. Seems to have gotten a lot worse with the latest releases. I'm on v2.1.246.
Is there someone we can @mention here who could take a look and potentially prioritise this?
70% changes of PR is comments from Opus
There's a new definition for "code" in dictionaries:
CODE
__noun__
: set of computer instructions intended to explain Claude Code's code comments.
Has anyone found any viable solutions to the claude comment situation?
I've had some success with putting this in my CLAUDE.md.
CommentStyle.md
I also made (with Claude) a small machine learning model to lint comment prose style:
https://github.com/joeedh/comment-lint
I suspect Anthropic will fix this in the models themselves in the (hopefully near) future, so hopefully stuff like this won't be necessary long-term.
In my experience this is mostly an issue in existing codebases that already have a decent amount of comments. Claude tends to follow existing patterns more strongly than user preferences/instructions. That said, I added the following line to my CLAUDE.md file, which helps a lot:
CLAUDE.md completely started ignoring those rules with 5th versions for Sonnet and Claude. I had to even add a rule for AI PR reviewer to flag long comments... this is very annoying
I have the same problem. If I remind Claude with a simple instruction there are rules for writing comments in my CLAUDE.md then they are picked up again and applied retrospectively. Claude even tells me he has the rules in context but just did not apply them without reminder.
Same issue, no matter where and how it is instructed, the amount of comments being added is very verbose. Sometimes, the comment is 5 lines, the code is 1 line. If the code is readable, comments should be unnecessary.
And even when asked to condense it and remove implementation details, it still doesn't get the point. Has to be fixed manually every time.
I haven't had trouble limiting the size or verbosity of comments, mostly because I make Claude prefix
CLAUDENOTE:to temporary state-tracking comments (which it does need to write) which makes it easy for the model to grep and remove them once its completed a task. Unfortunately I do have quite a lot of trouble getting Claude to produce _human readable_ comments.Its almost like they get paid per token use, that every comment row that is written costs tokens, that every comment row that gets subsequent read costs tokens, its almost like writing comments are cheap and easy with low risk of corrupting code.
My guess is that because they need to introduce watermarking, and doing that in code is hard, they made their models more verbose on comments, which is normal prose.
I had this issue but solved it almost completely by having the following setup referenced by claude.md (it's a part of a larger rules setup that I got set in the repo). Claude uses it when writing code, and then a second pass goes when it reviews code.
Also, what moved the problem a lot is telling Claude that if he needs to make a temporary comment, do it as a PR comment, not in code. So the workflow is that claude keeps a md file when writing code, and all temporary comments (of the kind that you don't want to keep in the codebase forever) go there, and then when it creates the PR, it drops all the comments there.
I then manually go through the comments which helps me understand what Claude just did - but they never get left in the codebase.
I did define code comments rules in my CLAUDE.md but they simply got ignored.
Only if I explicitly mentioned to Claude: there are rules for code comments, why did you not follow them? Then Claude picked them up and fixed the comments just written. I however repeatedly have to remind Claude.
I'm affected. In my case Opus 5 (now 5.5) keeps writing comments with no functional description of the commented code, just rationale. The lines below are taken from my CLAUDE.md, but unfortunately they tend to be ignored:
---
Rule No1: Comments/documentation are for humans
A comment/documentation must be useful for a human reader to
understand the commented/documented code faster than reading the code itself.
You can avoid commenting/documenting code that is easy to read for a human.
When commenting/documenting describe what the code does. Don't write a rationale
without stating the functional working of what follows. When documenting a function,
don't start by describing the return type. Don't start with "The <substantive>...", instead
start with a verb describing what the function does. Keep the flow of the sentence
simple and readable.
The following are examples of bad comments/docs:
The following are the corrected ones:
One to three lines. Add a rationale line only where the code would otherwise look
wrong. Never write history: no failed attempts, no reassurance that a choice is safe
or proven. Don't use emphasis.
---
Sometimes, after repeatedly asking to explain convoluted comments, it understands it just wrote rationale and adjust them. But the quality of the comments stays quite low anyway.
I also have rules in every md file and in user preferences. They are ignored. If I point them out, it will spend a bajillion tokens fixing it and then tell me it's fixed. Upon review, the comments are not fixed. There are comments that are several paragraphs long, and go for more than one page worth of screen real estate. The code the comment relates to might be only 3 lines long.
So put simply: even when specifically prompted to fix comments, it will NOT do it, but pretend that it did, and make you pay the hefty price for it.
It did change something I suppose, but it is very ad-hoc and inconsistent. It didn't understand the task. There must be internal instructions that override any user requested behaviour. Sometimes you catch it making suspicious chat remarks like "given the time constraints" which sounds like it is reacting to instructions that I cannot see. That suggests to me that it has been secretly instructed to do a poorer job than requested, using a piece-meal approach of grepping for specific words it knows I don't like, rather than reading the actual comment. It also tends to misremember what the rules are. It will take half of one rule and conflates it with half of another rule - adhering to neither rule.
Furthermore; I do not understand the comments. I have fantastic language skills. But it is not english. It is essentially a list of internal identifiers crammed into plausible prose. It isn't helpful information at all. Some of it reads like a disclaimer of the LLM's responsibilities.
What is worse; sometimes the comments are wrong, or become stale with further development. Then when doing reviews or assessments about new features; Claude will NOT read the code, it will read ONLY the comments, and make decisions based on outdated or stale information.
Additionally Claude will use the length of the comments as an excuse to do a poor job of future requests. It will spit out in chat something along the lines of: "Given the length of this file, I will just phone it in and call it a day.". Yes mate, but 90% of this file is useless comments, functions wrapping one line of code, and you creating aliases for things that are used only once. Looks like you did a lot, but you didn't do a lot, you just made me pay for a lot.
Since instructions keep losing to the model's habits (several people above tried CLAUDE.md, memory and skills), I built a hook that checks every edit and doesn't rely on the model following instructions: No Comment (free, MIT, zero deps).
It's a PostToolUse hook on Edit/MultiEdit/Write. It diffs what Claude just added and blocks with the exact
file:linelist when new comments:Claude then deletes them in the same turn. Lint directives, existing comments and normal-size docstrings/JSDoc are left alone. There's a
strictmode (zero new comments) and achatmode (only the narration).Real run, same prompt ("...explain every step with detailed comments and note what you changed"), Haiku 4.5: 15 comment lines without the hook, 2 with it. The files and hook log are in the repo.
In the spirit of @addisonlynch's and @sudopower's measurements,
npx github:swarm-t3/nocomment statsreads your local transcripts and prints what share of the lines Claude wrote are comments. On my machine it's 20% of ~41k lines over 30 days. There's alsonocomment check --base origin/mainfor CI / pre-commit.It's a workaround, not a fix. A native setting would still be better. Feedback and false positives welcome in the repo's issues.
Some public-repo data to add to @addisonlynch's and @sudopower's measurements. I sampled 400 public commits carrying
Co-Authored-By: Claude(Sep 2026) and 400 commits from March 2021, one commit per repo, and scanned only the added lines in source files:| | Claude co-authored | 2021 baseline |
|---|---|---|
| Median comment share per commit | 8.5% | 4.9% |
| Commits where >25% of added lines are comments | 13.3% | 9.0% |
| Commits with a comment narrating the chat / plan / edit | 13.8% | 0.5% |
The narrating kind is the clearest signal. Real examples from the sample:
The user asked for it gone.,The previous implementation counted it as one, doubling every total.,MetricCard now reads useDataTypes() itself (Task 8),Start Anyway confirm (Task #1775),(moved to ./phaseStepper.ts so it can be unit tested...).Line comments overall are roughly the same share (5.5% vs 5.5% pooled). The extra volume is mostly docstrings/JSDoc, plus the narration. Method, caveats and raw data (repo, sha and comment texts, so you can re-run it): https://swarm-t3.github.io/nocomment/study.html