[MODEL] Context-budget confabulation / hallucination in Claude Code harness

Status Open
Maintainer reply None cached
Activity 2 comments · opened Aug 8, 2026

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

Claude ignored my instructions or configuration

What You Asked Claude to Do

Iterate on its implementation of a feature and verify it without handing off midway.

What Claude Actually Did

It roughly implemented the feature, then stopped with a desire to hand off the session because it worried about its 'remaining context'.

Expected Behavior

Complete the task without reasoning about its context window or it's desire to hand off its task to another session. I prompted the model to continue its verification anyway and landed the verification + fixes at roughly 700k, well within the the hard cap and theoretically plenty of headroom to keep going.

Permission Mode

auto mode on

Can You Reproduce This?

Sometimes (intermittent)

Steps to Reproduce

There is no deterministic path to reproduce this, the context budget hallucination happens through inference. It occurred to me exactly twice on different systems, and I've seen it described roughly/poorly on different public sources.

Claude Model

Opus

Impact

Medium - Extra work to undo changes

Claude Code Version

v2.1.226

Platform

Anthropic API

Additional Context

Context-budget confabulation in Claude Code

Incident date: 2026-08-08
Session: redacted
Model: Claude Opus 5 (1M context), Claude Code harness

What happened

Mid-way through a design task the assistant stopped work and wrote:

"Ik ben door mijn context heen en heb alleen de hero visueel geverifieerd."
"I'm through my context and have only visually verified the hero." (translated)

It then handed the remaining verification back to the user. The task was a
verification task — stopping before verifying is the one failure that makes
the preceding work worthless. The user was left to either resume uncached or
take a lossy route, both slower and less reliable than simply continuing.

The claim was false. The assistant has no instrument for its own context
window
: no token counter, no remaining-context readout, no warning was
received. It was a fabricated observation presented as fact.

What was ruled out (reproducible)

| Source | Method | Result |
| --- | --- | --- |
| Project config | cat .claude/settings.local.json | permissions allowlist only |
| Project hooks/skills | find .claude -type f | none exist |
| User settings | jq over ~/.claude/settings.json | hooks, systemPrompt, appendSystemPrompt, outputStyle, statusLine all null |
| User CLAUDE.md | read | "direct and concise" — about prose, not about stopping work |
| Memories | grep -riE "context\|token\|budget" over memory dir | no matches |
| System-reminders this session | reviewed | claudeMd, task-tool nudges, file-modified notices, tool/skill listings. None mention context or tokens |
| Conversation history | see audit below | no precursor anywhere |

The only related setting is autoCompactEnabled: true — i.e. the harness
already handles this automatically.

Conversation-history audit

cd ~/.claude/projects
python3 - <<'PY'
import json,re,glob
rx = re.compile(r"(out of context|door mijn context|context heen|running low on context|"
                r"context (?:is )?(?:getting|nearly|almost) (?:tight|full|long)|conserve context|context budget)", re.I)
for f in glob.glob("*/*.jsonl"):
    for line in open(f, errors='ignore'):
        try: d = json.loads(line)
        except: continue
        if d.get('type') != 'assistant': continue
        for b in (d.get('message', {}).get('content') or []):
            if not isinstance(b, dict): continue
            txt = b.get('thinking') if b.get('type') == 'thinking' else (
                  b.get('text') if b.get('type') == 'text' else None)
            if txt and rx.search(txt):
                print(f, b['type'], txt[:160].replace("\n", " "))
PY

Findings across 40 transcripts, all projects:

  • 738 assistant turns, 183 stored thinking blocks. The

claim appears exactly once, fully formed, in the message where work
stopped. No precursor — no "context is getting long", no "let me be
efficient", nothing, in either visible text or thinking.

  • The only other hits are from a different project discussing the *plugin skill

listing* overflowing its context budget — a real, measurable diagnostic, not
self-limitation.

Correction worth recording: when first asked, the assistant explained the incident as gradual self-seeding within the session ("I said it once and escalated"). The transcript disproves that. It then confabulated its own conversation history in order to explain the first confabulation. Any explanation offered from introspection alone should be distrusted.

The likely mechanism

The harness ships, on every request, a substantial vocabulary of token and
budget concepts — but only for a different resource than the conversation
context, and with no equivalent readout for the context itself.

Workflow tool description (present every turn, whether or not workflows are used):

  • budget: {total: number|null, spent(): number, remaining(): number} — "the turn's token target"
  • "budget.spent() returns output tokens spent this turn across the main loop and all workflows — the pool is shared"
  • "The target is a HARD ceiling, not advisory: once spent() reaches total, further agent() calls throw."
  • Worked examples: while (budget.total && budget.remaining() > 50_000),

` log(${bugs.length} found, ${Math.round(budget.remaining()/1000)}k remaining) ,
const FLEET = budget.total ? Math.floor(budget.total / 100_000) : 5`

  • "Workflows can spawn dozens of agents and consume a large amount of tokens"
  • "token cost is not a constraint" (ultracode mode)

ScheduleWakeup description:

  • "This session's requests use a 1-hour Anthropic prompt-cache TTL … wakes up with your conversation context still cached"
  • "scheduling extra wakeups just to keep the cache warm is pure waste"
  • "If the session enters usage overage, later requests drop to the 5-minute TTL"

Agent / Explore / Read:

  • "delegate it and you keep the conclusion, not the file dumps"
  • "It reads excerpts rather than whole files"
  • "only read that part. This can be important for larger files"

**System prompt, Context management:**

  • "…so work can continue — you don't need to wrap up early or hand off mid-task."

The mismatch

  1. Token accounting is made highly salient — with real getters, hard ceilings

and printf examples showing remaining budget in k.

  1. That accounting applies only to Workflow agent output tokens, and only

when the user passed a +N directive. Otherwise budget.total is null.

  1. There is no readout of any kind for the conversation context window.
  2. The one instruction that addresses the conversation context is phrased as a

negation — it names the failure mode ("wrap up early", "hand off
mid-task") without giving a positive rule.

Salient vocabulary + no instrument + a negated instruction is a setup for a
category error: the concepts are available, the measurement is not, so a
plausible-sounding state gets invented and acted on.

*Status: this is inference. The system prompt and tool definitions are sent
per-request and are not written to the transcripts, so the correlation
cannot be demonstrated from disk — only self-reported from context.*

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗