Summary
When an LLM gets stuck repeating failed approaches, context rot has set in. Clean slate recovery solves this by starting a fresh session with explicit constraints about what didn’t work and why. This prevents the LLM from repeating failed paths and costs less than continuing a broken trajectory.
The Problem
After 3+ failed attempts at solving a problem, LLMs accumulate negative context (failed implementations, error messages, dead-end approaches) that pollutes future generations. The LLM gets stuck in a loop, repeatedly suggesting the same failed approaches or variations that still don’t work. The conversation context becomes a liability rather than an asset.
The Solution
Terminate the current session and start fresh with a clean context. In the new session, explicitly state: (1) what the previous approach was, (2) why it failed, and (3) constraints to avoid repeating the failure. This gives the LLM a fresh start while preserving the learning from failures, allowing it to explore new solution paths without negative context accumulation.
The Problem
You’re working with an AI coding agent, trying to fix a bug or implement a feature. The first attempt doesn’t work. Neither does the second. By the third attempt, you notice something troubling: the LLM keeps suggesting variations of approaches that have already failed.
This is context rot—the accumulation of negative context that poisons future generations.
How Context Rot Happens
LLMs are stateful within a conversation. Every failed attempt adds to the context:
Attempt 1: "Try using JWT refresh tokens"
→ Implementation fails
→ Error messages added to context
→ Failed code added to context
Attempt 2: "Let's modify the JWT approach"
→ Still fails
→ More error messages
→ More failed code
→ Context now contains 2 failed implementations
Attempt 3: "How about adjusting the JWT validation?"
→ Still fails
→ Even more errors
→ Context now polluted with 3 failed JWT attempts
Attempt 4: "Maybe we need to tweak the JWT expiration..."
→ You're stuck in a loop
The LLM is now anchored on the JWT approach because the entire conversation history is saturated with JWT-related attempts. It can’t easily escape to explore fundamentally different solutions.
The Cost of Continuing
Continuing a broken trajectory has real costs:
- Time cost: Each failed iteration takes 2-5 minutes
- Token cost: Large context windows with error messages are expensive
- Mental cost: Developer frustration compounds
- Opportunity cost: Better solutions go unexplored
After 3 failed attempts (15+ minutes), you’ve likely spent more time than starting fresh would take.
Recognition Signals
You know context rot has set in when:
- Same approach, different variation: “Let’s try X… okay, how about X with Y… maybe X with Z?”
- Circular reasoning: The LLM refers back to failed attempts as if they might work now
- Error message accumulation: Context fills with stack traces and error logs
- Decreasing suggestion quality: Later suggestions are worse than early ones
- The “stuck” feeling: You sense the conversation is going nowhere
The Solution: Clean Slate Recovery
Clean slate recovery is a deliberate pattern for escaping bad trajectories.
The Pattern
1. Recognize trajectory is broken (3+ failed attempts)
2. Terminate current conversation/session
3. Start new session with clean context
4. Frame the problem with constraints:
- "Previous approach: X"
- "Why it failed: Y"
- "Constraints: Must do A, cannot do B"
5. Let LLM explore fresh solution space
Why It Works
Clean context = fresh perspective
By removing negative context accumulation, the LLM can:
- Explore different solution branches not anchored to failed attempts
- Consider fundamentally different approaches without JWT/previous-solution bias
- Apply learning from failures through explicit constraints
- Generate with higher quality since context isn’t polluted
Learning without baggage
The key insight: You don’t need the failed implementations in context—you only need the lessons learned expressed as constraints.
❌ Bad (keeping failure context):
"Here's the JWT code that failed with error X...
And here's the modified JWT code that failed with error Y...
And here's another JWT variation that failed with error Z...
Can you try something else?"
✅ Good (clean slate + constraints):
"Implement authentication.
Context: Previous approach using JWT refresh tokens didn't work
because our API doesn't support refresh endpoints.
Constraints:
- Must use session-based auth only
- Cannot modify backend API
- Must handle 401 responses gracefully
Suggest an approach."
The second prompt gives the LLM all the information it needs to succeed, without the cognitive burden of processing failed attempts.
Implementation
Step 1: Recognize the Pattern
Set a 3-attempt threshold. If you haven’t made progress after 3 attempts, trigger clean slate recovery.
// Mental checklist
const shouldRestart = (
attempts >= 3 &&
(sameApproachRepeated || solutionQualityDeclining || feelingStuck)
);
if (shouldRestart) {
// Time for clean slate
}
Step 2: Document What Failed
Before terminating the session, capture:
- What approach was tried
- Why it failed (root cause, not just symptoms)
- What constraints were violated
## Session 1 Learnings
Approach: JWT refresh token authentication
Failure reason:
- API doesn't expose refresh token endpoint
- Cannot modify backend (external service)
- JWT approach requires refresh capability
Constraints discovered:
- Backend is read-only (cannot add endpoints)
- Must work with existing session-based auth
- Need to handle token expiration gracefully
Step 3: Start Fresh Session
Open a new conversation/session. This ensures:
- Clean context window
- No accumulated error messages
- Fresh token budget
- Psychological reset for both you and the LLM
Step 4: Frame with Constraints
Structure your prompt to include:
# Task
[Clear description of what you need]
# Context: Previous Approach
[One sentence: what was tried]
# Why It Failed
[One sentence: root cause]
# Constraints
[Bullet list: what must/cannot be done]
# Request
[What you want the LLM to do]
Step 5: Verify New Direction
Before implementing, ask the LLM to:
- Confirm it understands the constraints
- Propose approach before writing code
- Explain why this approach avoids previous failures
This prevents immediately falling into another bad trajectory.
Examples
Example 1: Authentication Bug
Session 1 (Failed trajectory):
You: "Fix the authentication bug where users get logged out"
LLM: "Let's add JWT refresh tokens..."
→ Fails (API doesn't support refresh)
You: "That didn't work, API error"
LLM: "Try storing refresh token in localStorage..."
→ Fails (still no API endpoint)
You: "Still failing"
LLM: "Maybe we need to adjust the token validation..."
→ Fails (API design issue, not validation)
[Stuck in JWT refresh loop]
Session 2 (Clean slate recovery):
You: "Implement authentication that keeps users logged in.
Context: Previous approach tried JWT refresh tokens but failed because
our API doesn't expose refresh endpoints and we cannot modify the backend.
Constraints:
- Must use session-based auth (API provides session cookies)
- Cannot modify backend API (external service)
- Must handle 401 responses by redirecting to login
- Should persist session across page refreshes
Suggest an approach."
LLM: "Since we're using session-based auth, we can:
1. Let the API handle session cookies (automatic)
2. Add axios interceptor to catch 401 responses
3. On 401, clear local state and redirect to login
4. Sessions persist via httpOnly cookies (secure)
This avoids JWT refresh complexity and works with existing API."
→ Success! Completely different approach.
Example 2: Performance Optimization
Session 1 (Failed trajectory):
You: "Optimize the slow dashboard query"
LLM: "Add indexes on user_id and created_at..."
→ Marginal improvement (2.1s → 1.9s)
You: "Still too slow"
LLM: "Add composite index on (user_id, created_at, status)..."
→ Minimal improvement (1.9s → 1.8s)
You: "Not enough"
LLM: "Try adding index on organization_id too..."
→ No improvement (1.8s)
[Stuck in index-adding loop]
Session 2 (Clean slate recovery):
You: "Optimize slow dashboard query (currently 1.8s).
Context: Previous approach tried adding various indexes but only improved
from 2.1s to 1.8s (14% improvement, not enough).
Why it failed: The query joins 5 tables and fetches 50+ columns.
Indexes can't solve the fundamental issue of too much data transfer.
Constraints:
- Target: <200ms response time
- Cannot change database schema
- Can add caching, materialized views, or denormalization
Suggest approach."
LLM: "The issue is data transfer volume, not query planning.
Suggestions:
1. Add materialized view for dashboard data (refreshed every 5 min)
2. Return only needed columns (currently fetching 50+, only show 8)
3. Add Redis cache for user-specific dashboard (5 min TTL)
This targets the root cause (too much data) rather than query planning."
→ Implementation: 1.8s → 120ms (93% improvement)
Example 3: Type Error Hell
Session 1 (Failed trajectory):
You: "Fix TypeScript errors in user service"
LLM: "Add type assertion: user as User..."
→ Errors persist
You: "Still failing"
LLM: "Try casting: (user as any) as User..."
→ Compiles but runtime errors
You: "Runtime errors now"
LLM: "Use type guard: if (isUser(user))..."
→ Doesn't solve underlying issue
[Stuck in type-casting loop]
Session 2 (Clean slate recovery):
You: "Fix type errors in user service.
Context: Previous attempts tried type assertions and casts but
this just masked the underlying problem.
Why it failed: The API returns UserDTO but our code expects User.
Type assertions don't solve the shape mismatch.
Constraints:
- Cannot change API response format
- Must maintain type safety (no 'any')
- Need runtime validation
Suggest approach."
LLM: "The issue is DTO-to-domain mapping. Solution:
1. Create explicit mapper: userDtoToUser(dto: UserDTO): User
2. Add runtime validation using zod schema
3. Call mapper at API boundary
4. Use proper User type everywhere else
This solves the shape mismatch properly instead of hiding it with casts."
→ Type-safe solution that handles the actual problem
Best Practices
1. Set a Threshold
Establish a 3-attempt rule:
Attempt 1: Try LLM's first suggestion
Attempt 2: Try refinement/variation
Attempt 3: Try alternative approach
If attempt 3 fails → Clean slate recovery
Don’t wait for 5-10 attempts. Early reset is cheaper.
2. Capture Root Cause, Not Symptoms
When documenting failures:
❌ Bad: "Got error: Cannot read property 'id' of undefined"
✅ Good: "API sometimes returns null instead of user object"
❌ Bad: "Authentication keeps breaking"
✅ Good: "JWT refresh requires /refresh endpoint which doesn't exist"
❌ Bad: "Query is slow"
✅ Good: "Query transfers 50+ columns but only 8 are displayed"
Root cause understanding prevents repeating the failure.
3. Be Specific with Constraints
❌ Vague: "Make it work with the existing API"
✅ Specific: "API provides session cookies via Set-Cookie header.
Cannot add new endpoints. Must use existing /login and /logout."
❌ Vague: "Fix the performance issue"
✅ Specific: "Target <200ms response. Can add caching/materialized views.
Cannot change database schema (production database)."
Specific constraints guide the LLM to viable solutions.
4. Verify Understanding First
Before implementation:
You: [Clean slate prompt with constraints]
LLM: [Proposes approach]
You: "Before implementing, confirm:
1. Does this approach satisfy all constraints?
2. Why won't this hit the same failure as the JWT approach?
3. What's the key difference from the previous failed attempts?"
LLM: [Explains reasoning]
You: "Great, proceed with implementation."
This verification step prevents immediately jumping into another bad trajectory.
5. Know When NOT to Reset
Don’t reset if:
- Making steady progress (each attempt improves)
- Only 1-2 attempts (too early)
- Issue is environmental (wrong API key, network error)
- You haven’t provided enough context (add context first, then retry)
Reset when:
- Same approach variations (“try JWT… try JWT + X… try JWT + Y…”)
- Quality declining (suggestions getting worse)
- Circular references (“let’s go back to approach 1…”)
- Feeling stuck (intuition is valuable)
Integration with Other Patterns
Combine with Trust But Verify Protocol
Before accepting an LLM suggestion in a new session:
- Verify it addresses the root cause
- Check it satisfies all constraints
- Confirm it’s not a variation of what failed
See: Trust But Verify Protocol
Combine with Plan Mode Strategy
Instead of implementing immediately after clean slate:
- Ask LLM to propose 2-3 approaches
- Evaluate approaches against constraints
- Select best approach
- Then implement
Iterating on plans is cheaper than iterating on implementations.
See: Plan Mode Strategy
Combine with Context Debugging Framework
If your tool supports it, use systematic debugging to prevent rot:
- Detect declining quality (test failure rate, same suggestions)
- Debug systematically (context → prompting → model power → manual)
- If debugging doesn’t help → Clean slate
See: Context Debugging Framework
Measuring Success
Success Metrics
Track clean slate recovery effectiveness:
interface RecoveryMetrics {
oldSessionAttempts: number; // How many attempts before reset
oldSessionCost: number; // Token cost of failed session
newSessionAttempts: number; // Attempts in new session to solve
newSessionCost: number; // Token cost of new session
totalTime: number; // Total time to solution
solved: boolean; // Did clean slate solve it?
}
// Example
const metrics: RecoveryMetrics = {
oldSessionAttempts: 5, // 5 failed attempts
oldSessionCost: 15000, // 15K tokens wasted
newSessionAttempts: 1, // Solved on first try
newSessionCost: 3000, // 3K tokens used
totalTime: 22, // 22 minutes total
solved: true, // Success!
};
// If we had continued old session:
// Likely: 8-10 more attempts = 35+ minutes, 35K+ tokens
// Clean slate saved: ~13 minutes, ~17K tokens
Key Indicators
Good reset decision:
- New session solves in 1-2 attempts
- Fundamentally different approach
- Lower token cost than continuing would have been
Premature reset:
- New session has same issues
- Should have added more context instead
- No new insights gained
Too late reset:
- Wasted 6+ attempts before resetting
- High token costs in failed session
- Developer frustration accumulated
Common Pitfalls
❌ Pitfall 1: Not Documenting Why Approaches Failed
Problem: Reset without capturing lessons
You: "That didn't work. Let me start over."
[New session]
You: "Implement authentication"
LLM: "Let's try JWT refresh tokens..."
→ Immediately repeats the same failed approach
Solution: Always document constraints in new session
❌ Pitfall 2: Resetting Too Quickly
Problem: Reset after 1 failed attempt
Attempt 1: Fails due to typo
→ Reset session immediately
[New session]
→ Still fails because the typo was in your code, not LLM's
Solution: Follow 3-attempt threshold
❌ Pitfall 3: Vague Constraints
Problem: Don’t provide specific constraints
You: "Previous approach didn't work. Try something else."
→ LLM doesn't know what to avoid
→ Might repeat the same approach
Solution: Be explicit about constraints
❌ Pitfall 4: Carrying Baggage
Problem: Copy-paste failed code into new session
[New session]
You: "Here's the code that didn't work: [500 lines]
Can you fix it?"
→ Brings negative context into new session
→ Defeats the purpose of clean slate
Solution: Only bring constraints, not failed implementations
❌ Pitfall 5: Not Verifying New Approach
Problem: LLM immediately implements without discussing approach
[New session with constraints]
LLM: "Here's the implementation: [generates 200 lines]"
→ Might be heading down wrong path again
→ No chance to course-correct before implementation
Solution: Ask for approach proposal first
Cost Analysis
Scenario: Continuing Failed Trajectory
Attempts 1-3: Already failed (15 min, 15K tokens)
Attempts 4-6: Likely to fail (15 min, 15K tokens)
Attempts 7-8: Maybe succeeds? (10 min, 10K tokens)
Total: ~40 minutes, ~40K tokens
Success rate: ~30%
Scenario: Clean Slate Recovery
Attempts 1-3: Failed attempts (15 min, 15K tokens)
Documentation: Capture learnings (2 min)
New session: Fresh start (8 min, 5K tokens)
Total: ~25 minutes, ~20K tokens
Success rate: ~80%
Savings
Time saved: 15 minutes (37% reduction)
Token saved: 20K tokens (50% reduction)
Success rate: +50 percentage points
Key insight: Clean slate becomes profitable after attempt 3. The longer you wait, the less you save.
Conclusion
Clean slate recovery is a proven pattern for escaping bad LLM trajectories.
When to use:
- 3+ failed attempts
- LLM suggesting variations of same approach
- Context accumulating error messages
- Feeling “stuck in a loop”
How to use:
- Recognize pattern (3-attempt threshold)
- Document what failed and why
- Start fresh session
- Frame with explicit constraints
- Verify new approach before implementing
Benefits:
- Escapes negative context accumulation
- Explores fundamentally different solutions
- Costs less than continuing broken trajectory
- Higher success rate
- Preserves learning without baggage
Key principle: You don’t need failed implementations in context—you only need the constraints they revealed.
The result: Faster problem-solving, lower costs, and less frustration.
Related Concepts
- Context Debugging Framework – Systematic approach to diagnosing AI generation issues
- Trust But Verify Protocol – Verifying LLM suggestions before implementation
- Plan Mode Strategy – Iterating on plans instead of implementations
- Verification Sandwich Pattern – Test → Implement → Verify workflow
- Five-Point Error Diagnostic Framework – Structured error analysis approach
- Error Messages as Training Data – ERRORS.md provides constraints for clean slate prompts
- Prevention Protocol – Document lessons learned from failed trajectories as prevention measures
- Test-Based Regression Patching – Use failing tests as constraints when starting fresh sessions
References
- Context Window Management in LLMs – Understanding how context accumulation affects LLM performance

