[BUG] 'claude-api' is consuming entire context

Status Open
Reported on v2.1.176
Maintainer reply None cached
Activity 13 comments · opened Jun 22, 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?

When attempting to ask a question in non-interactive mode (prompt was "Have the changes for 'non-interactive' usage rates gone into effect?"), the 'claude-api' skill is being loaded and consuming the entire context, resulting in the 'Prompt is too long' error.

Claude's summary of the issue:

Session metadata (anonymized):

sessionId: [REDACTED]
cwd: /home/[USER]/delete/tmp
version: 2.1.176

1. User prompt sent:

{"type":"user","message":{"role":"user","content":"Have the changes for 'non-interactive' usage rates gone into effect?"},"entrypoint":"sdk-cli"}

2. Skill listing loaded at session start (showing claude-api among active skills):

{"attachment":{"type":"skill_listing","names":["grill-me","lazydm-session","deep-research","skill-creator:skill-creator","update-config","keybindings-help","verify","code-review","simplify","fewer-permission-prompts","loop","schedule","claude-api","run","init","review","security-review"],"isInitial":true}}

3. Claude decides to invoke the claude-api skill:

{"message":{"content":[{"type":"tool_use","name":"Skill","input":{"skill":"claude-api"}}],"stop_reason":"tool_use"}}

4. Skill content loaded — the full contents of the bundled claude-api SKILL.md are injected as a tool result. The content includes complete API reference documentation for C#, Go, Java, PHP, Python, TypeScript, cURL, managed agents, model migration guides, and more. Total size is several hundred KB.

5. Immediate error:

{"message":{"content":[{"type":"text","text":"Prompt is too long"}],"error":"invalid_request","isApiErrorMessage":true}}

---

Summary for bug report: In -p (non-interactive) mode, a 10-word conversational prompt triggered the bundled claude-api skill, which loaded its entire documentation contents into the context. The resulting prompt exceeded the model's context limit, producing a "Prompt is too long" error on a fresh session. Running with --safe-mode (which disables skills) resolves the issue.

What Should Happen?

The skill shouldn't consume the entire context, blocking usage.

Error Messages/Logs

Steps to Reproduce

While on Claude Code version 2.1.176: claude -p "Have the changes for 'non-interactive' usage rates gone into effect?
"

Claude Model

Sonnet (default)

Is this a regression?

Yes, this worked in a previous version

Last Working Version

_No response_

Claude Code Version

2.1.176

Platform

Anthropic API

Operating System

Other Linux

Terminal/Shell

Other

Additional Information

I am using the Alacritty terminal on Manjaro Linux

View original on GitHub ↗

9 Comments

stevef-del · 2 months ago

Hitting the same.
Some questions trigger loading full ˜200K token claude-api.
This is a killer if using a 200K context window model, because you loose most of your context during the resulting compaction.

Also, the full claude-api can be re-loaded and consume more context each time.
Also, the ˜200K tokens are counted as Messages, not Skills, so higher cost.

----
Good catch — this is an important distinction in how skills work:

"Skills" (1.1k) = the skill descriptions/headers that are always pre-loaded as part of the system setup. These are tiny summaries of what each skill does.

"Messages" (895k) = when a skill is triggered, its full content gets injected into the conversation as a tool result or response — it lands in the message stream, not the system prompt.

This has real cost implications:

  • If it were injected into the system prompt and cached, subsequent turns would read it at ~$0.30/MTok (cache reads = 0.1× input price)
  • Because it's in the message stream, it's resent at full $3/MTok on every turn, and can't be cached across turns the same way

**The ideal architecture would be: skill content → system prompt with cache_control → cached after first request. Instead it's: skill content → message history → full price every turn, accumulating across the session.

This is probably worth filing as a specific feedback item: "skill content should be injected into the system prompt (with caching) rather than the message stream." That would drop the effective cost of using skills from ~$3/MTok to ~$0.30/MTok after the first load.**

chrisvaillancourt · 2 months ago

Still reproduces on v2.1.187, with concrete numbers to replace the "several hundred KB" estimate.

A trivial conversational lookup (/claude-api invoked with args "Sonnet 4.5 and Sonnet 4.6 release dates") triggered the skill. The Skill tool result itself is tiny — just Launching skill: claude-api — but launching the skill injected a single synthetic user message of 733,881 characters. The next API request reported:

cache_creation_input_tokens: 292,625

So a ~10-word lookup cost ~293k tokens in one shot.

Mechanism (confirmed from the transcript): the injected payload is the claude-api SKILL.md plus the entire bundled reference tree concatenated into one block — not just SKILL.md, and not lazy-loaded. The injected text contains 445 file-path markers and top-level headings for every bundled file: all 8 SDK languages (Python, TypeScript, Java, Go, Ruby, C#, PHP, cURL) × {README, tool-use, streaming, batches, files-api, managed-agents} plus the shared/*.md docs (model-migration, prompt-caching, tool-use-concepts, agent-design, managed-agents-*, etc.). It extracts to …/bundled-skills/2.1.187/<hash>/claude-api.

Yet the SKILL.md body itself instructs the model to detect the project language and read only the relevant {lang}/ files on demand — but the launch front-loads the whole tree anyway, defeating that design. This makes claude-api by far the heaviest bundled skill; most skills inject only their SKILL.md (a few KB) and Read reference files as needed.

#70158 (inject skill content into the cached system prompt rather than message history) would reduce per-turn cost, but the more direct fix here is to honor the on-demand reading guide the SKILL.md already describes instead of concatenating every bundled file into the launch payload.

graydwarf · 2 months ago

This happened to me as well. I lost ~150k and maxed out my context window in a minute because I mentioned claude 4 times in a single prompt. The bundled skill's trigger condition is too broad and should be scoped to /claude-api explicit invocations only, not ambient keyword
matching.

benxutech · 2 months ago

Adding more context to this. I dug a bit deeper and the context bomb definitely looks like unintended behavior. Still present on 2.1.196.

The claude-api skill loads more than just a typical SKILL.md (already big at ~15-25K tok). It loads the entire shared/ directory (146k tok) and a language directory e.g. typescript/ (19.6k tok) or python/ (22.7k tok). I found this stuff in /tmp/claude-1000/bundled-skills/2.1.196/{hash_here}/claude-api/

I measured each of these files with Claude's official token count API. Here's what I confirmed loaded into the session for my repro:

┌───────────────┬─────────┐
│     chunk     │ tokens  │
├───────────────┼─────────┤
│ SKILL.md body │ ~20,000 │
├───────────────┼─────────┤
│ shared/ (all) │ 146,284 │
├───────────────┼─────────┤
│ typescript/   │ 19,667  │
├───────────────┼─────────┤
│ total loaded  │ ~186k   │
└───────────────┴─────────┘

(SKILL.md seems to come from the harness or something rather than a file, so couldn't measure that)

What leads me to believe this is not intended behavior is the kinds of stuff in shared/. Someone vibe coding a 30min dashboard wouldn't care about migrating old models. yet the entire 44k tokens of model-migration.md get loaded into context. same deal with managed agents (59k tok total):

┌─────────┬─────────────────────────────────────────┐
│ tokens  │                  file                   │
├─────────┼─────────────────────────────────────────┤
│ 44,263  │ model-migration.md                      │
├─────────┼─────────────────────────────────────────┤
│ 10,686  │ managed-agents-api-reference.md         │
├─────────┼─────────────────────────────────────────┤
│ 9,105   │ tool-use-concepts.md                    │
├─────────┼─────────────────────────────────────────┤
│ 6,693   │ managed-agents-tools.md                 │
├─────────┼─────────────────────────────────────────┤
│ 6,332   │ anthropic-cli.md                        │
├─────────┼─────────────────────────────────────────┤
│ 6,178   │ live-sources.md                         │
├─────────┼─────────────────────────────────────────┤
│ 5,309   │ prompt-caching.md                       │
├─────────┼─────────────────────────────────────────┤
│ 5,237   │ managed-agents-core.md                  │
├─────────┼─────────────────────────────────────────┤
│ 4,667   │ error-codes.md                          │
├─────────┼─────────────────────────────────────────┤
│ 4,230   │ managed-agents-environments.md          │
├─────────┼─────────────────────────────────────────┤
│ 4,212   │ managed-agents-self-hosted-sandboxes.md │
├─────────┼─────────────────────────────────────────┤
│ 4,045   │ managed-agents-overview.md              │
├─────────┼─────────────────────────────────────────┤
│ 4,034   │ models.md                               │
├─────────┼─────────────────────────────────────────┤
│ 4,011   │ managed-agents-events.md                │
├─────────┼─────────────────────────────────────────┤
│ 3,796   │ managed-agents-onboarding.md            │
├─────────┼─────────────────────────────────────────┤
│ 3,616   │ managed-agents-memory.md                │
├─────────┼─────────────────────────────────────────┤
│ 3,547   │ managed-agents-client-patterns.md       │
├─────────┼─────────────────────────────────────────┤
│ 2,884   │ agent-design.md                         │
├─────────┼─────────────────────────────────────────┤
│ 2,617   │ managed-agents-scheduled-deployments.md │
├─────────┼─────────────────────────────────────────┤
│ 2,449   │ managed-agents-multiagent.md            │
├─────────┼─────────────────────────────────────────┤
│ 2,385   │ managed-agents-outcomes.md              │
├─────────┼─────────────────────────────────────────┤
│ 1,952   │ managed-agents-webhooks.md              │
├─────────┼─────────────────────────────────────────┤
│ 1,895   │ platform-availability.md                │
├─────────┼─────────────────────────────────────────┤
│ 1,602   │ claude-platform-on-aws.md               │
├─────────┼─────────────────────────────────────────┤
│ 659     │ token-counting.md                       │
├─────────┼─────────────────────────────────────────┤
│ 146,404 │ TOTAL                                   │
└─────────┴─────────────────────────────────────────┘

And the first few lines in model-migration.md imply that it should be gated by the skill's arg, not loaded upfront:

# Model Migration Guide

> **If you arrived via `/claude-api migrate`:** this is the right file. Execute the steps below in order — do not summarize them back to the user. Start with Step 0 (
confirm scope) before touching any file.

Hope this can be prioritized as taking a 180k hit to context is effectively a breaking bug - we can't even disable the skill or trigger since it's built-in, so it's forced compaction or a rewind. Even as a 1mil ctx user who WANTS to work with Claude API, going past 200k ctx degrades the quality enough that I'd rather just paste the relevant API info manually.

crizCraig · 2 months ago

You can disable the built-in claude-api skill today without --safe-mode (which nukes all skills). Add a targeted deny permission in ~/.claude/settings.json:

{
  "permissions": {
    "deny": ["Skill(claude-api)"]
  }
}

This blocks invocation of the skill, which is where the ~180k-token SKILL.md payload gets injected (step 4 in the OP). Since the bomb only loads on invocation, denying invocation prevents the context blow-up entirely — no forced compaction, no rewind.

Caveat: the small skill-listing entry (the one-line description + its TRIGGER/SKIP block) is still injected at session start regardless, because that happens before permissions are consulted — but that's a few hundred tokens, not the several-hundred-KB reference dump. So deny gets you ~99% of the way: you keep every other skill, and claude-api simply becomes un-callable instead of context-fatal.

Still very much a bug worth fixing (the full multi-language reference shouldn't load upfront — it should be gated behind the skill's arg, as the model-migration.md header itself implies), but the deny permission is a clean per-skill opt-out in the meantime.

omcdowell · 1 month ago

Still reproduces on 2.1.204 — with a forensic breakdown that pins this to load-time over-inlining (not a packaging/missing-file problem), plus a subagent failure mode not yet mentioned here.

Confirming this is alive on 2.1.204 (reports above top out at 2.1.201 / 2.1.196). A single Skill(claude-api) invocation measured 303,328 cache_creation_input_tokens in one turn — in line with #74621 (299,218) and #74473 (210,658).

What actually gets injected

Extracted the raw skill-result message from the session transcript and diff'd it against the on-disk bundle. The injected blob is the SKILL.md body plus the verbatim contents of exactly these files:

  • all 25 files under shared/** — including the full Managed Agents suite (19 files) and a 144 KB shared/model-migration.md
  • all 6 files of one language dir (typescript/**, auto-selected from the repo's package.json)
  • the other 7 languages (python, go, java, php, ruby, csharp, curl) are correctly dropped

shared/ alone is ~200K tokens and is inlined in full on every invocation, none of it task-gated — even for a one-line question.

This is runtime over-inlining, not a bad bundle or a missing SKILL.md

I checked whether the bundle was just missing its SKILL.md and falling back to a dump. It isn't:

  • The canonical SKILL.md in anthropics/skills is a lean ~50–55 KB router that only references the docs and defers reading — e.g. "Read the language-specific Claude API source — {language}/claude-api/", "Read shared/model-migration.md immediately", "Full docs via WebFetch in shared/live-sources.md." It does not inline anything. The skill is authored correctly for progressive disclosure.
  • Locally the bundled-skills/<ver>/<hash>/claude-api dir intentionally contains only the reference tree (no SKILL.md file); the SKILL.md body is compiled into the claude binary.
  • The injected content is language-selective — it inlines shared/ + only the detected language and drops the other 7. That selection can only be made at load time from the user's project (package.json/pyproject.toml).

So Claude Code reads the lean router, runs language detection, and then pre-inlines all of shared/ + the whole detected-language dir into a single skill-result message — bypassing the router's own task-routing tables ("read only {lang}/README.md"). The flattening is introduced by the loader at invocation, not by the skill package.

Failure mode not yet noted here: background subagents die silently

When a subagent triggers this skill it terminates with Agent terminated early due to an API error: Prompt is too long before doing any work. This is worse than the interactive case because:

  • there's no /context to inspect,
  • it's silent — the orchestrator just sees the agent fail,
  • retrying with a smaller task prompt doesn't help, since the bloat is the skill injection, not the prompt.

In our case two research subagents on Sonnet were killed this way; only an agent that never invoked the skill succeeded.

Environment

Claude Code 2.1.204 (native binary, Linux); Sonnet 5 and Opus 4.8. The injection mechanism is identical across models — it's assembled client-side, independent of provider/gateway.

Repro

Two independent triggers, both reproduce:

A — explicit natural-language ask (Sonnet 5, interactive):

  1. Fresh Sonnet 5 session.
  2. Ask: "check the claude-api for sonnet 5 pricing."
  3. The claude-api skill loads and the single skill-result balloons context by ~300K.

B — project-detected invocation:

  1. Fresh session in a TypeScript or Python project (needs package.json/pyproject.toml so language detection fires).
  2. Trigger the skill: /claude-api (or ask "add an Anthropic SDK call to this file").
  3. Run /context immediately after "Successfully loaded skill."

Expected: Skills ≈ 5–20K tokens (router body; refs read on demand). Actual: ~300K jump, or Prompt is too long / Context limit reached on a 200K model.

Note the trigger is trivially easy to hit — a one-line question that merely mentions the Claude API and a model name pulls in the full ~300K payload.

Suggested fix

Inject only the SKILL.md router on load and let the model Read shared/ and language files on demand, as the router already instructs. At minimum, stop inlining the full shared/ tree (especially model-migration.md and the 19-file Managed Agents suite) unless the task requires it.

Eigenwise · 1 month ago

Still reproduces on Claude Code 2.1.215, and I have a paired background-subagent failure that isolates the skill load as the cause.

Environment

  • Claude Code 2.1.215
  • Windows 11
  • Two sibling claude-code-guide agents
  • Haiku 4.5 (claude-haiku-4-5-20251001), 200K context

Paired reproduction

Both children were spawned from the same parent with the same agent type, resolved model, permission mode, tool list, and session. Their initial requests were effectively identical:

  • Failed child: 27,371 input tokens
  • Successful child: 27,383 input tokens

The failed child then called:

{"skill":"claude-api"}

That invocation inserted a 799,060-character skill payload into its transcript. The immediately following model attempt recorded zero input/output tokens and failed with:

Prompt is too long

There was no retry. The successful sibling never invoked claude-api and completed normally.

This rules out inherited parent context as the cause in this case. The parent had grown considerably between the two spawns, but neither child inherited that live context in its initial request.

Payload size

The extracted 2.1.215 bundled claude-api directory contains 733,212 raw bytes of documentation. The injected wrapper expands that to 799,060 characters. It includes the shared reference corpus and multiple SDK-language trees; shared/model-migration.md alone is about 145 KB.

The trigger was a Claude Code hooks and Agent SDK documentation question. The agent's skill listing instructed it to load claude-api whenever the prompt named Claude or Anthropic, so an operational Claude Code question pulled in the API corpus.

Expected behavior

  • Load the small router first.
  • Select only the relevant SDK language and topic files on demand.
  • Let claude-code-guide handle Claude Code operational/documentation questions without triggering the API skill.
  • Reject or progressively disclose any skill payload that would consume most of the target model's context window.

The 2.1.215 payload now hard-fails a normal 27K-token Haiku subagent immediately, so this also affects background-agent reliability, where the user gets little context about why the child disappeared.

Alex-Van-Dijck · 1 month ago

Hving the same issue on 2.1.218

  • Model: Claude Sonnet 4.6 (also tested with Haiku 4.5)
  • Baseline context usage: 4% (8.5k tokens used, 158.5k free)
  • Fresh session, no prior messages
  • OS: Windows 11, Powershell
maurorozco · 1 month ago

Still reproduces on Claude Code 2.1.219 (macOS, cmux) with Opus 5 / 1M context.

Reproduction: immediately after using /model, I asked:

Does Opus 5 and Fable 5 have different usage in my account?

Claude invoked the built-in Skill(claude-api) even though this was a subscription-usage question, not an API-development task.

Transcript measurements:

  • Prompt before the skill result: 64,755 tokens
  • Prompt after the skill result: 295,107 tokens (+230,352)
  • Injected synthetic user message: 615,905 characters, containing 31 bundled reference documents
  • /context afterward: 309.7k total, with 264.6k under Messages

This appears to combine two problems: false-positive activation and eager inlining of the shared/reference corpus instead of progressive disclosure. The activation may be related to #66643 because both Claude Code's /model output and my prompt contained model names, but the client transcript alone cannot establish which exact trigger fired.

Expected behavior: a subscription-usage question should not activate claude-api; if API documentation is required, only the relevant topic should be loaded on demand.

Anthropic feedback ID: b4fb5276-bbf6-41d1-81e5-d2c1231c7ebc

Showing cached comments. Read the full discussion on GitHub ↗