All writing

Claude Code Felt Off for a Month. Here Is What Broke.

Three overlapping bugs caused four weeks of subtle Claude Code regressions that no standard test suite would have caught.

For about four weeks in March and April, Claude Code felt noticeably worse. We were not imagining it. Sessions got repetitive. Tool calls chose weird paths. Usage limits emptied faster than the work we got out of them. We kept switching models, clearing context, restarting CLIs, convinced we had broken something in our own setup.

Then on April 23 Anthropic published a postmortem. Three separate bugs, all resolved by April 20. Usage limits were reset for every subscriber as compensation. The apology was thorough. The more interesting part is what the timeline reveals about the failure modes of agent products, and what that means for any developer building on top of one.

TL;DR

The three bugs overlapped. All three felt like the same thing to users: Claude got dumber. None would have been caught by a normal test suite.

| # | Window | Bug | Fix | | --- | ---------------- | -------------------------------------------------------------------------- | -------------- | | 1 | Mar 4 to Apr 7 | Reasoning effort default lowered from high to medium for latency | Reverted Apr 7 | | 2 | Mar 26 to Apr 10 | Cache cleared "thinking blocks" every turn after 1h idle, not once | CLI v2.1.101 | | 3 | Apr 16 to Apr 20 | Prompt capped responses to 25 or 100 words, cost 3% benchmark intelligence | CLI v2.1.116 |

The three bugs, expanded

Bug 1: the silent default change

On March 4, Anthropic lowered the default reasoning effort from high to medium to reduce latency. A product call, not a bug, with a defensible rationale. Users noticed anyway. Reverted April 7.

Lesson: a "config" change to an agent's reasoning budget is a model change. It deserves a changelog entry. Quietly tuning it down to hit a latency target is the kind of decision that reads reasonable in a meeting and awful in a transcript.

Bug 2: the caching regression

This one is the scariest of the three. A prompt-cache optimization shipped March 26. The intent: clear "thinking blocks" from the cache once, after an hour of inactivity. The implementation cleared them on every turn after that first hour.

The symptom was that Claude became forgetful. It repeated itself. It picked strange tools. It burned through usage quotas far faster than the same session would have a week earlier. None of that raised an HTTP 500 or fired a test alert. It only manifested as "this feels worse."

The cache was supposed to do this:

t=0:  start session, thinking blocks written to cache
t=1h: cache cleared once due to inactivity
t=1h+1turn: normal flow resumes, new thinking blocks cached

Instead it did this:

t=0:  start session, thinking blocks written to cache
t=1h: cache cleared due to inactivity
t=1h+1turn: new thinking blocks cached... then cleared
t=1h+2turn: thinking blocks cached... then cleared
[repeat every turn]

Each turn paid the full cost of re-deriving reasoning from scratch, and lost the prior context.

Bug 3: the word-limit constraint

Someone added this to the system prompt on April 16:

keep text between tool calls to ≤25 words.
keep final responses to ≤100 words.

Reads fine. Even looks like the kind of instruction we might write to tighten our own agents. What it actually did: clip the model by roughly 3% across the benchmark suite. Reverted April 20.

What we learned running projects on top of this

Two lessons stuck.

Agent regressions are diffuse. A classic API regression has a clear signal. The test fails, the error rate spikes, the latency chart moves. An agent regression shows up as "our work feels worse." The only way we caught anything was by noticing we were redoing work more often, not because a metric turned red. If you are building tools that route to an agent, you need a drift signal that does not rely on exceptions or HTTP status codes.

Caching is the most dangerous optimization in agent systems. The bug with the biggest blast radius read, on paper, as a small optimization with an obvious upside. The failure mode stayed invisible until you imagined what happens when "clear thinking blocks after inactivity" runs every turn instead of once. We have pulled back on aggressive cache-invalidation heuristics since reading this.

If you cannot prove the cache key captures every meaningful state change, pay for the tokens.

What this means for tool builders

1. Version your prompts

Every system prompt our tooling ships now embeds a version string in a trailing comment. Git tells us the same thing, but an ad hoc marker is faster to spot in a transcript.

const SYSTEM_PROMPT = `You are a writing assistant.
Follow the style guide. Prefer short sentences for impact.
<!-- prompt-v: 2026-04-23.3 -->`;

When a session feels off, grep for the version in the transcript. If it has drifted, you know where to look.

2. Log tokens per turn

A silent spike in tokens-per-turn is exactly what the caching bug would have produced. That was not a thing we were watching for.

logger.info("turn", "completed", {
  turn: turnIndex,
  inputTokens: usage.input_tokens,
  outputTokens: usage.output_tokens,
  cacheHit: usage.cache_read_input_tokens ?? 0,
  promptVersion: "2026-04-23.3",
});

A rolling average of input tokens per turn is a cheap drift detector. If it doubles on a Tuesday and your code has not changed, the thing underneath you has.

3. Stop testing agents with toy tasks

The bugs Anthropic describes would not have shown up in a short demo. They only surface in sessions that run long enough for the agent to need its earlier reasoning, or for the cache to kick in.

| Eval type | Catches bug 1? | Bug 2? | Bug 3? | | ---------------------------- | :------------: | :----: | :----: | | Single-prompt accuracy bench | maybe | no | no | | Short multi-turn demo | no | no | maybe | | 30-minute real session | yes | yes | yes |

If you benchmark an agent for production use, your evaluation needs sessions that last half an hour of real work or more. Anything shorter gives false confidence.

The tradeoff nobody is naming

Here is the uncomfortable part. The fixes Anthropic describes are the kind you only find by rolling back and listening to complaints. Each of the three initial changes shipped with a reasonable-sounding justification.

| Change | Stated reason | Actual cost | | ------------------------- | ------------------- | ------------------------------------- | | Lower default effort | Latency matters | Perceived IQ drop | | Cache aggressively | Money matters | Thinking history destroyed every turn | | Constrain response length | Readability matters | 3% benchmark hit |

The problem is that agent quality is multi-dimensional, and the postmortem made visible something most vendors quietly hope users do not notice. You cannot A/B test an agent the way you A/B test a search ranker. The feedback loop is noisy, delayed, and routed through the subjective experience of people who already had a rough day.

Anthropic did the right thing by publishing the timeline. Most vendors do not.

The bottom line

Three bugs, four weeks, an ecosystem of developers quietly wondering if they should switch tools.

Short evals would not have caught any of them. Prompt versions, per-turn token logging, and long-session evals are the minimum viable drift detectors.

When you build on top of an agent, you are depending on a product team's prompt, their cache policy, and their default settings. All three can change without a version bump you would notice.

Read the full postmortem at anthropic.com/engineering/april-23-postmortem. Then look at whether your own tooling would have caught any of these regressions.

Source: devto.

More from GLINR Studios.