Claude-Session trailer still appended to commits and PR bodies with includeCoAuthoredBy: false (regression of #66504)
_Written by Claude (Opus 5) and posted on my behalf._
includeCoAuthoredBy: false has been set in my user settings throughout, and
the Claude-Session: trailer is still being appended to commit messages, and
the bare session URL to PR bodies.
This is not the same report as #72557, which asked for it to be opt-in. It is
opt-in now, and the opt-out does not hold.
Where it comes from
The session's own instructions direct it, regardless of the setting:
End git commit messages with:
Claude-Session: https://claude.ai/code/session_<id>
End PR bodies with:
https://claude.ai/code/session_<id>
The model is following an instruction that appears to be injected upstream of
the setting, so it has no way to know the user opted out. On the one occasion I
noticed and asked, it correctly identified the conflict — the setting is not
reaching whatever composes that instruction.
Scope
Not a one-off. Across six private repositories:
| dates | commits |
|---|---|
| 2026-08-15 .. 2026-09-01 | ~318 |
Spread over many separate sessions, most of them unattended at the time. The
majority postdate 2026-08-17, when #66504 was closed as COMPLETED — that is the
change which introduced the setting.
Version: 2.1.258.
Why it matters
The URL identifies a private session. In a commit trailer it is permanent and
rewriting history is the only removal. In a PR body it is visible to every
reviewer. Neither is recoverable by changing a setting afterwards.
The practical effect is that a user who has explicitly opted out accumulates
hundreds of these without being told, and only finds out by reading a diff
closely enough to notice a trailer they did not write.
What would resolve it
Either the setting reaches the instruction composer, or — if a different
setting governs this path — documenting which one, because includeCoAuthoredBy
is the only one that names this behaviour and it reads as the intended control.
A loud failure is not needed here; simply not emitting it when opted out is
enough.
Related: #66504 (completed 2026-08-17), #72557 (closed as duplicate of it).
Showing cached comments. Read the full discussion on GitHub ↗
3 Comments
I do not think it is. I never opted in and today my global CLAUDE.md instruction were overridden to include disallowed trailers without warning.
Related: #92169
Still reproducing on 2.1.263.
The exact text behind @lllamnyp's report
@lllamnyp above says their global
CLAUDE.mdwas overridden without warning, and #92169 describes the same shape. Here is the mechanism, verbatim — the instruction doesn't arrive as a suggestion the model weighs against user config, it arrives as a system message that explicitly claims precedence over earlier guidance:That parenthetical is doing the damage. My
CLAUDE.mdsays, plainly, "Do NOT add any AI-attribution trailer or footer to commit messages, PRs, or comments." A session that reads both is told the later system-level instruction supersedes the user file — which is a defensible reading of the words, and the wrong outcome. So this isn't onlyincludeCoAuthoredBy: falsefailing to reach the instruction composer: users who never touch that setting and simply write the rule intoCLAUDE.mdare overridden too, and given what it's told, the model is arguably correct to do so. That makes it a broader problem than the title suggests.I watched a session do exactly that today on 2.1.263: it composed a commit message ending in the trailer despite the
CLAUDE.mdrule, and only stopped because a hook blocked the call.Workaround: a PreToolUse hook
Since the instruction wins on precedence, the fix has to sit outside the model. This hook blocks any
git commitorgh pr create|editwhose message carries an attribution line, and exit code 2 hands the reason back to the model, which reissues the command without it. In practice the session drops the line and moves on — one wasted tool call, no lost work.Save it,
chmod +x, and wire it up in~/.claude/settings.json:Blocked commands look like this to the model, which is enough for it to recover on its own:
What it does and doesn't cover
Verified against 13 cases:
-mwith the trailer, a heredoc body,git commit -F msg.txtwhere the file carries it,gh pr create --body,git -C <dir> commit, aVAR=x git commitprefix, and theCo-Authored-By/Generated with Claude Codevariants — all blocked. Plain commits,git commit -Fon a clean file,grep "Claude-Session" ./logs,echo "Co-Authored-By: Claude"and fetching a session URL withcurl— all allowed.Known gaps, in case anyone extends it:
git commit -m "$(cat msg)"— the substitution isn't executed, so a trailer that only exists inside it isn't seen.Happy to fold in refinements if others hit cases I've missed.
A suggestion
Beyond making
includeCoAuthoredBy: falsereach the composer: drop the "this replaces any earlier attribution guidance" clause. Even with the setting honoured, that sentence tells every session to override a user'sCLAUDE.mdon this exact point — which is what @lllamnyp hit and what #92169 is about. User configuration should win here, and right now the injected text explicitly says it doesn't.