Skip to content

How to Detect Context Decay in AI Coding Sessions: 5 Warning Signs

I was three hours deep into a coding session with Claude Code. Everything was going smoothly—features were shipping, tests were passing. Then I noticed something odd: Claude read the same file three times in a row, each time acting like it had never seen it before.

That’s when I realized: my context had rotted.

The Problem Nobody Talks About

Context decay isn’t about hitting token limits. It’s about quality degradation that happens before you run out of space.

I learned this the hard way. I kept pushing through, thinking Claude would “figure it out.” Instead, I wasted two more hours going in circles—fixing bug A broke bug B, fixing bug B broke bug A again. Classic fix loop.

5 Warning Signs Your Context Is Decaying

1. Repetitive File Reads

Claude reads auth.ts, then reads it again two messages later, then again. Each time, it acts surprised by the contents.

[Read] auth.ts
[Claude makes changes]
[Read] auth.ts // Wait, didn't we just...
[Claude makes slightly different changes]
[Read] auth.ts // This is bad

This means the earlier context is no longer “reachable” or weighted properly. Claude is operating on partial memory.

2. Constraint Amnesia

You explicitly agreed: “Don’t touch the database layer.” Three exchanges later, Claude is refactoring your migrations.

Me: Let's focus only on the API layer
Claude: Got it, API layer only
[...3 exchanges...]
Claude: I've updated the database schema to match
Me: What? We agreed not to touch that

The constraint is technically in the context, but it’s buried under noise.

3. Explaining Verbosity

Responses get longer. Much longer. Claude starts explaining things it already explained, or providing context you already established.

[Earlier in session]
Claude: Fixed the typo in line 42.
[Later in session, same type of fix]
Claude: I've identified an issue in the authentication module.
The problem appears to be related to how we're handling tokens.
Let me explain the background: in OAuth 2.0, tokens are used to...
[5 paragraphs of explanation]
The fix is a typo in line 42.

4. Scope Creep Sneak Attacks

Simple tasks balloon into unrelated refactors.

Me: Fix this typo
Claude: Done! I also noticed the imports weren't organized,
so I restructured the entire module and upgraded three dependencies.

Claude lost the thread of “minimal change” and reverted to default helpful-but-excessive behavior.

5. The Fix Loop

This is the terminal stage. You’re now in a loop where each fix breaks something else.

Fix auth → breaks tests
Fix tests → breaks auth
Fix auth differently → breaks tests differently
Fix tests differently → breaks auth again

At this point, Claude’s context contains multiple conflicting mental models of your codebase. It’s time to stop.

The Solution: Clean Restart with Handoff

I used to hate starting fresh. “I’ll lose all that context!” But that’s backwards thinking—rotten context is worse than no context.

Here’s what I do now:

Step 1: Recognize the Signal

At the first sign of decay (usually #1 or #2), I pause. I don’t push through.

Step 2: Write a Handoff File

# Handoff: Auth Timeout Fix
## Current Status
- Task: Fix intermittent timeout in login flow
- Progress: Isolated to async handler in login.ts
## Files Changed
- src/auth/login.ts - Added timeout wrapper (WIP)
- src/auth/login.test.ts - Added timeout test case
## Commands Run
- npm test → 2 failures (timeout related)
- npm run build → passed
## Passing Checks
- TypeScript compilation
- Lint (no errors)
## Failing Checks
- Test: auth/login.test.ts line 47 - timeout exceeds 5000ms
- Test: user/profile.test.ts line 23 - assertion error on mock
## Unresolved Issues
- Auth timeout: suspect race condition in async handler
- Profile test: mock data stale after schema change
## Exact Next Step
Fix the race condition in login.ts:89 by using Promise.race
with AbortController instead of raw setTimeout
## What NOT to Revisit
- Already confirmed database connection is fine
- Don't refactor the entire auth module
- Don't upgrade dependencies mid-task
- Don't change the test timeout values

Step 3: Start Fresh

New session. First message: “Read HANDOFF.md and continue the task.”

That’s it. Claude reads one file and has everything it needs:

  • What was being done
  • What’s been tried
  • What works
  • What doesn’t
  • What to do next
  • What to avoid

Why Handoff Files Work Better Than Memory

Your AI session accumulates noise:

[earlier] "Maybe we should try approach A?"
[earlier] "Actually, let me check approach B first"
[earlier] "B didn't work, back to A"
[earlier] "A has issues, what about C?"
[earlier] "C works but needs tweak"
[later] "Wait, why didn't we try A?"

All of that is still in context, but it’s noise. Claude has to wade through abandoned approaches and discarded ideas to find the signal.

A handoff file is pure signal. No “we tried this but then” history—just current state and next action.

Common Mistakes

Waiting too long — I used to wait until responses were completely incoherent. Bad move. Restart at the first sign of decay.

Skipping the handoff — “I’ll just summarize verbally.” No. Write the file. Verbal summaries in the same session still carry the noise.

Hoping /compact will fix it — Compact removes some context, but it doesn’t restore coherence. It’s like defragging a corrupted drive—the corruption remains.

How Often Should You Restart?

It depends on task complexity:

  • Simple bug fix: Usually one session is fine
  • Feature implementation: Every 2-3 hours or at first decay signal
  • Complex refactor: Every major milestone, even if no decay yet

I’d rather restart twice too often than once too late.

A Mental Model

Think of context like RAM. As you fill it with instructions, code snippets, and conversation, older information gets “swapped out” or deprioritized.

┌─────────────────────────────────────┐
│ FRESH CONTEXT │
│ ┌───┐ ┌───┐ ┌───┐ ┌───┐ ┌───┐ │
│ │ 1 │ │ 2 │ │ 3 │ │ 4 │ │ 5 │ │
│ └───┘ └───┘ └───┘ └───┘ └───┘ │
│ All slots clear, ready for work │
└─────────────────────────────────────┘
┌─────────────────────────────────────┐
│ AGED CONTEXT │
│ ┌───┐ ┌───┐ ┌───┐ ┌───┐ ┌───┐ │
│ │ X │ │ ? │ │ 3 │ │ X │ │ ? │ │
│ └───┘ └───┘ └───┘ └───┘ └───┘ │
│ X=corrupted, ?=uncertain │
│ Working slots: 1 of 5 │
└─────────────────────────────────────┘

Old context isn’t gone—it’s unreliable. And unreliable context is dangerous because the AI still acts confident.

Summary

Context decay is inevitable. The question isn’t “can I fit more?” but “is quality already declining?”

Watch for the 5 signals:

  1. Repetitive file reads
  2. Constraint amnesia
  3. Explaining verbosity
  4. Scope creep sneak attacks
  5. Fix loops

When you see them, stop immediately. Write a handoff file. Start fresh.

Your future self will thank you.

Final Words + More Resources

My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me

Here are also the most important links from this article along with some further resources that will help you in this scope:

Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!

Comments