[BUG] Literal "HERMES.md" in git commit messages triggers 400 "out of extra usage" on Max OAuth (content filter false-positive misclassified as quota error)
Summary
A literal HERMES.md string (uppercase + dot + md, case-sensitive) appearing anywhere in git log of the current working directory causes Claude Code on a Claude Max OAuth plan to return:
API Error: 400 {"type":"error","error":{"type":"invalid_request_error","message":"You're out of extra usage. Add more at claude.ai/settings/usage and keep going."}}
The error message is misleading — the Max plan has plenty of quota. This appears to be a server-side content filter false-positive (likely matching the canonical doc filename of an external AI project) that misroutes the request to the disabled "extra usage" lane.
Minimal Reproduction (10 lines, deterministic)
mkdir /tmp/repro-hermes && cd /tmp/repro-hermes
git init -q
echo a > a.txt && git add .
git commit -m "HERMES.md" # exact case + .md is the trigger
claude
# > hi
# Result: API Error 400 "You're out of extra usage..."
Removing .git/ or rewording the commit message makes the error disappear instantly.
Trigger Specificity (case-sensitive byte match)
| Commit message | Result |
|---|---|
| HERMES.md | ❌ 400 |
| hermes.md | ✅ OK |
| Hermes.md | ✅ OK |
| HERMES (no .md) | ✅ OK |
| HERMES.txt | ✅ OK |
| HERMES md (no dot) | ✅ OK |
| 6 HARD GUARDS (other capitalized phrase from same commit) | ✅ OK |
The filter matches the literal byte sequence HERMES.md only — no case normalization.
What's not a trigger
| Scenario | Result |
|---|---|
| File named HERMES.md in working tree (no git) | ✅ OK |
| File content containing HERMES.md (no git) | ✅ OK |
| Auto-loaded CLAUDE.md containing HERMES.md text (no git) | ✅ OK |
| Env var HERMES_WEBHOOK_URL | ✅ OK |
The trigger is specifically in the bytes Claude Code derives from git log and sends as system context.
Real-world reproduction
A repo with 50 commits where 12 messages referenced HERMES.md returned 400 every time. Diagnosis path:
- Shallow clone
--depth 1or--depth 2(fewer than 3 commits visible) → ✅ works --depth 3(commit607afc8 docs(...): HERMES.md 13-point review...becomes visible) → ❌ failsgit filter-repo --message-callback ...replace(b"HERMES.md", b"hermes-doc.md")→ permanent fix
Why this matters
- The error message is wrong. Claims quota exhaustion when none exists, sending users to billing settings unnecessarily. Content-filter rejection misclassified as quota error.
- It silently blocks legitimate use. "Hermes" is a perfectly reasonable name (Greek mythology, classical themes, internal service names) and
.mdis standard for markdown docs. - No actionable feedback. Users have no way to know the rejection is content-driven; the diagnostic path I followed (move CLAUDE.md → move .claude/ → remove project entry → bisect git history → bisect commit by commit → bisect message text → bisect words) took several hours.
Suggested fixes
- Don't classify content-filter rejections as billing errors. Return a distinct error type (e.g.,
content_filter_rejected) so clients can surface accurate messages. - Reduce false-positive scope. Matching the literal byte sequence
HERMES.mdis too broad. Consider context-aware filtering, not bare substring match in free-form text. - Document any system-context content that could be rejected so users can debug.
Environment
- Claude Code: v2.1.119 (latest)
- Plan: Claude Max 5x (OAuth,
rateLimitTier=default_claude_max_5x) - Platform: Linux 6.8 (Ubuntu)
- Auth:
~/.claude/.credentials.json, noANTHROPIC_API_KEYset - Date observed: 2026-04-25
- Related issues: #45020, #45033, #45028, #45095, #45390 (general "out of extra usage" reports — this is the first to identify a specific deterministic content-filter trigger)
---
Original real-world commit message that surfaced this bug
For full transparency / so engineers can analyze the byte sequences in case there is additional sub-pattern matching beyond the minimal HERMES.md trigger I isolated, here is the exact unmodified commit message in the repo that originally triggered the 400. Submitting verbatim because filter rules sometimes match on combinations / surrounding characters / unicode (em-dashes etc.) that minimal repros may not capture:
docs(session-118): HERMES.md 13-point review — profile model fix, schema, 6 HARD GUARDS, v0.11.0 notes
The 4 other commits in the same repo that also had HERMES.md in the message:
docs(session-118): update HERMES.md version to v0.11.0
docs: HERMES.md — Session 97c-fix5 Reviewer1 fallback + EP9 deprecation troubleshooting
- HERMES.md: Section 6 5-Layer Framework + ownOrderPlanId subsection + BANNED hindsight
HERMES.md updates:
- NEW HERMES.md (915 lines, 14 sections) — comprehensive Hermes Agent dev doc
Any of these in git log (depth ≥ that commit) → 400. Bisecting reduced the trigger down to HERMES.md alone, but the real-world messages contained additional content (em-dashes, parentheses, (session-NNN) prefix, all-caps phrases like BANNED, HARD GUARDS, version strings, etc.) that may share weight in whatever classifier is rejecting these.
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗