Claude Code writes a component using the wrong import style. You correct it. Next file, same mistake. You add a rule to your CLAUDE.md. Works for one session, then breaks again. You restart. Works again. Then does not.
This is not random. There are specific, diagnosable causes for each of these patterns, and each one has a different fix. Running through them in order takes less time than randomly tweaking your config and hoping something sticks.
Step 1: Check your CLAUDE.md before assuming anything else
The most common cause of wrong output is not a Claude bug or a context issue. It is a CLAUDE.md that does not actually say what you think it says.
Before anything else, open your CLAUDE.md and look for these specific problems:
- The rule is vague. "Write clean imports" is not a rule. "Use named exports only, no default exports, group imports as: built-in, external, internal, separated by blank lines" is a rule.
- The rule exists but is buried. Claude reads your entire CLAUDE.md, but rules near the top of prominent sections carry more weight. A single bullet in a long list is easy to de-prioritize.
- You only said what to do, not what to avoid. If your project uses Vitest but your CLAUDE.md only says "use Vitest for tests," Claude might still reach for Jest because the negative instruction is missing. Add: "Do not use Jest. Do not use Mocha."
- The rule contradicts something else in the file. Two sections saying different things about the same behavior create ambiguity. Claude picks one.
If your CLAUDE.md has any of these problems, fixing them is your first move. Everything else on this list is downstream of a solid config.
The ContextKit Analyzer scores your file across five categories and shows you specifically which sections are weak or missing. Paste your CLAUDE.md, get a score, and look at which categories are below 1.5 out of 2. Those are where the gaps are.
Step 2: Context window overflow (when Claude forgets mid-session)
Claude Code has a fixed context window. In a long session with lots of file reads, code generation, and back-and-forth, the oldest content gets dropped to make room for new content. Your CLAUDE.md is loaded at the start of the session. If the session runs long enough, parts of it fall out of the window.
The symptom is specific: Claude follows a rule early in the session, then stops following it later. Same session, same rule, different behavior. This is almost always context overflow.
How to tell: look at how long the current session is. If you have done 30 or more substantial exchanges, read multiple large files, and worked across several different parts of the codebase, you are likely in overflow territory.
The fix is to start a new session. Claude reloads your CLAUDE.md fresh from the top, and the rules are back in full context. You lose the session history, but you gain a Claude that follows your conventions again.
To reduce how often this happens, keep your CLAUDE.md focused. Every line you add to CLAUDE.md is loaded into every session. A 400-line file that includes project history, deployment notes, and architecture explanations is using context that could be keeping your rules in window. Trim it to what actually changes Claude's coding behavior.
Step 3: Ambiguous instructions that Claude reads differently
Some rules fail not because they are missing but because Claude interprets them differently than you intended. This is especially common with instructions that have implicit assumptions.
A real example: a developer adds "use functional components" to their CLAUDE.md. They mean React functional components, no class components. Claude understands this. But Claude also continues using default exports because "functional components" says nothing about export style. The developer assumed the rule covered it. Claude read it literally.
Another common case: "follow the existing patterns in the codebase." This sounds comprehensive. In practice, if the codebase has inconsistent patterns (which most real codebases do), Claude picks one of them. Which one depends on what it found most recently. The result is technically compliant with your instruction but not what you wanted.
The test for an ambiguous instruction: can you look at any piece of Claude's output and immediately tell whether it followed the rule or violated it? If there is any ambiguity in how you would answer that, the instruction is ambiguous to Claude too.
Fix ambiguous rules by making them concrete and checkable:
# Before (ambiguous)
Use functional components and follow existing patterns.
# After (concrete)
- Only functional components. No class components.
- Named exports only. No default exports.
- Props interface named ComponentNameProps, defined above the component.
- No inline styles. Tailwind classes only.
- useCallback and useMemo only for proven performance issues, not by default. Step 4: Missing .claude/rules/ files for team conventions
Your CLAUDE.md lives at the project root. But you can also create a .claude/rules/ directory with additional rule files. Claude Code reads any .md files in this directory as supplementary project instructions.
Many teams put team-wide conventions in CLAUDE.md and project-specific rules in .claude/rules/. If the rules directory exists but some files are missing, Claude gets a partial picture of your conventions. It follows what it can find and falls back to defaults for the rest.
Check whether your project has a .claude/rules/ directory:
ls .claude/rules/
If the directory exists, check that all the rule files are present and not empty. Common rule files that get accidentally omitted: git.md (git safety rules), testing.md (test conventions), security.md (what never to commit).
If you are working on a team and cloned a repo, these files should be in version control. If they are in .gitignore, every team member needs to add them manually. That is a common gap.
Step 5: The "works on first try, breaks on retry" pattern
This one is specific: Claude generates correct code on the first attempt. You ask it to modify or extend that code. The second version breaks a rule the first version followed.
The cause is stale context. When Claude edits existing code, it reads the existing file to understand what is there. If the existing code has patterns that conflict with your CLAUDE.md rules (legacy code, code from before you added the rule), Claude picks up those patterns from the file and they compete with your explicit instructions.
Example: your CLAUDE.md says "no default exports." You have an old component that uses a default export. Claude reads that component, generates a new version, and mirrors the default export pattern from the original because it just read it.
The fix has two parts. First, make the rule emphatic in your CLAUDE.md:
# Conventions
- Named exports ONLY. No default exports under any circumstances.
- If editing a file with a default export, convert it to named export as part of the task. Second, when asking Claude to modify existing code that has legacy patterns, explicitly call out the pattern conflict: "This file uses default exports but our convention is named exports. Fix that as part of this task."
Step 6: Using the Analyzer to find config gaps
If the above checks do not surface the problem, the issue is probably a missing section you have not thought to add. The ContextKit Analyzer is useful here because it checks for categories you might not realize are missing.
Paste your CLAUDE.md and look specifically at the categories scoring below 1 out of 2:
- Low structure score: Your file does not tell Claude where things go. This explains wrong directory placement and missed existing utilities.
- Low architecture score: Your file does not describe how layers connect. This explains Claude putting business logic in the wrong place or introducing the wrong patterns.
- Low testing score: No test framework or command specified. This explains wrong test framework, skipped tests, or tests placed in the wrong location.
- Low guardrails score: No negative rules. This explains Claude doing things you did not want but never explicitly prohibited.
The analyzer gives you specific suggestions for each low-scoring category. Add those sections to your CLAUDE.md, run through a few tasks, and check whether the problematic behavior is gone.
Step 7: When to restart a session vs when to fix the config
These are two different fixes for two different problems. Using the wrong one wastes time.
Restart the session when:
- Claude was following a rule earlier in the session but stopped following it later
- The session has been running for a while and involved reading many files
- You just added a new rule to CLAUDE.md and want Claude to pick it up immediately
- Claude seems to be working from assumptions that were true 20 exchanges ago but are no longer relevant
Fix the config when:
- The problem happens in the first 5-10 exchanges of a fresh session
- The same mistake recurs across multiple separate sessions
- You have never seen Claude follow this particular rule, even in short sessions
- The same error appears in different projects that share similar configs
Session restart fixes context overflow and picks up config changes. Config fixes eliminate the root cause. If you are always restarting sessions to get correct behavior, you have a config problem you are treating as a session problem.
Real examples: what the mistake looks like and where to find the fix
Wrong import style
Claude generates import React, { useState } from 'react' when you want just import { useState } from 'react' (React 17+ JSX transform does not need the React import).
Where to look first: CLAUDE.md conventions section. The rule "no unused React imports" or "use automatic JSX transform, do not import React unless using React APIs directly" fixes this immediately.
# Conventions
- React 18 project. Do not import React unless using React.forwardRef, React.memo,
or similar. JSX transform handles the rest.
- No `import React from 'react'` at the top of component files. Ignoring the test framework
Your project uses Vitest. Claude writes describe and it blocks, imports from @jest/globals, and expects Jest to run the tests.
Where to look first: CLAUDE.md testing section, or lack of one. Add:
# Testing
- Framework: Vitest (not Jest)
- Run all tests: `npx vitest`
- Run single file: `npx vitest run src/utils/format.test.ts`
- Import from 'vitest': `import { describe, it, expect, vi } from 'vitest'`
- Do not import from '@jest/globals' or use jest.fn(). Use vi.fn() for mocks. Creating files in the wrong directory
You ask Claude to add a new utility function. It creates src/components/dateUtils.ts instead of src/lib/date.ts.
Where to look first: CLAUDE.md file structure section. Without explicit mapping, Claude reads the directory listing and makes a judgment call. Add a structure section:
# File Structure
- src/components/ -- React components only. No utility functions or business logic.
- src/lib/ -- Utility functions, helpers, business logic. One file per domain.
- src/hooks/ -- Custom React hooks only.
- src/types/ -- TypeScript interfaces and types. No runtime code.
- src/pages/ -- Next.js pages/routes only. Thin files that import from components and lib.
With this in place, Claude knows that a utility function belongs in src/lib/, not src/components/.
Creating a new file instead of editing the existing one
You ask Claude to add a function to your auth service. It creates src/lib/auth-v2.ts instead of editing src/lib/auth.ts.
Where to look first: this is usually a vague instruction problem. "Add a password reset function" does not tell Claude whether to create a new file or edit an existing one. More explicit: "Add a resetPassword() function to the existing src/lib/auth.ts file."
You can also prevent the pattern in CLAUDE.md:
# Rules
- Before creating a new file, check whether the functionality fits in an existing file.
- Do not create versioned files (auth-v2.ts, utils-new.ts). Edit the existing file. Summary: the debugging order
When Claude Code produces wrong output, work through this order:
- Check CLAUDE.md for vague, missing, or contradictory rules for the specific behavior that is wrong
- If the problem started mid-session after working correctly: context overflow. Start a new session.
- If the rule exists but Claude interprets it differently: make the rule more specific and add a negative version
- If you are on a team: check whether
.claude/rules/files are all present - If editing existing code triggers the problem: add a rule that explicitly overrides patterns from existing code
- Run your CLAUDE.md through the ContextKit Analyzer and fix any category scoring below 1.5
Most wrong output traces back to step 1. The config has a gap, and Claude fills it with training defaults. Every other item on this list is a real cause, but less common than a CLAUDE.md that looks complete but does not actually cover the behavior you want.
If you want to audit your config thoroughly before debugging further, the ContextKit Analyzer surfaces the gaps in under a minute. Low scores in specific categories point directly at the rules you need to add.
You might also like
Want to build your own AI OS?
The AI OS Blueprint gives you the complete system: 53-page playbook, working skills, and a clonable repo. Starting at $47.
30-day money-back guarantee. No subscription.