Skip to content

Common Mistakes

Common prompting mistakes when using Claude Code, and how to avoid and recover from them.

Senior engineers make predictable mistakes when starting with Claude Code. This guide covers the top issues, why they happen, and how to fix your workflow.

Mistake 1: Accepting Code Without Reading It

What happens: Claude generates 50 lines of tests that all pass. You commit. Two weeks later, you discover the tests don’t actually test the behavior they claim to — they pass because they’re testing the wrong thing.

Why it happens: Claude writes plausible code. Tests that call the right methods with reasonable data and make assertions that happen to pass look correct at a glance.

How to fix it:

  • Read every test Claude writes. For each assertion, ask: “Does this actually test what I care about?”
  • For critical code, manually trace the test: “If I introduced bug X, would this test catch it?”
  • Use /diff after every edit. Scan for unintended changes.

Recovery prompt:

> Read the test file. For each test, tell me: what bug would this
  test catch? If a test can't catch a specific bug, it's probably
  testing the wrong thing.

Mistake 2: Letting Claude Over-Implement

What happens: You ask for a simple email validation. Claude adds email validation, password validation, username uniqueness checking, rate limiting, and logging. You now have code you didn’t ask for, didn’t review, and didn’t test.

Why it happens: Claude tries to be helpful and anticipate what you need. For senior engineers, this feels like scope creep.

How to fix it:

  • Always specify scope: “Just implement email validation. Nothing else.”
  • Use TDD to control scope — Claude can only implement what you’ve tested
  • Review /diff to catch extra additions

Recovery prompts:

> Remove everything except the email @ check. We haven't written
  tests for password validation yet.
> That's more than I asked for. Revert to only the changes for
  [specific requirement].

Mistake 3: Asking for Everything at Once

What happens: You prompt “Build a complete inventory management system with stock tracking, reservations, transfers, and reporting.” Claude generates hundreds of lines. Some of it works, some doesn’t, and it’s impossible to review.

Why it happens: Claude can handle large requests, but the output quality drops as scope increases. And you can’t meaningfully review 300 lines of generated code.

How to fix it: Break it into pieces:

Step 1: "Add stock tracking with addStock and removeStock methods"
Step 2: "Now add availability checking across warehouses"
Step 3: "Add reservations with expiration"

Each step is small enough to review, test, and commit independently.

Mistake 4: Not Using /clear Between Tasks

What happens: You review a security vulnerability in file A, then ask Claude about file B. Claude’s response to file B is colored by the security context from file A — it flags false security concerns or makes assumptions based on the wrong file.

Why it happens: Claude maintains conversation context. Context from previous tasks bleeds into the current one.

How to fix it: Use /clear when:

  • Switching between unrelated files
  • Switching from review to feature building
  • When Claude seems confused about what you’re working on
  • After finishing a multi-step task

Mistake 5: Vague Review Prompts

What happens: You ask “review this code” and get 20 findings spanning security, style, naming, performance, and documentation. The critical SQL injection is buried among suggestions to rename variables.

Why it happens: Without direction, Claude tries to give comprehensive feedback. But comprehensive does not equal useful.

How to fix it: Be specific about what you want:

> Review ONLY for security vulnerabilities. Skip everything else.

And ask for severity:

> Categorize as CRITICAL, IMPORTANT, or MINOR. I only want to see
  CRITICAL issues right now.

Mistake 6: Not Providing Context

What happens: Claude gives generic advice because it doesn’t know what the code does or why it matters.

Why it happens: Claude can read code structure but can’t infer business context. “This is a payment processor” changes everything about how Claude reviews.

How to fix it: Add one sentence of context:

> This service processes credit card refunds. We've had duplicate
  refund issues in production. Review for idempotency problems.

Context changes what Claude prioritizes:

  • Without context: generic code quality feedback
  • With “handles payments”: focuses on correctness, error handling, idempotency
  • With “high-traffic endpoint”: focuses on performance, caching, rate limiting

Mistake 7: Fighting Claude Instead of Redirecting

What happens: Claude does the wrong thing. You repeat the same instruction more emphatically. Claude does the same wrong thing.

Why it happens: Repeating a prompt that didn’t work won’t make it work. Claude is interpreting your words differently than you intend.

How to fix it: Use /clear and rephrase:

/clear
> Read line 32-45 of UserRegistrationService.java. Add a single null
  check for the email parameter on line 33. If null, throw
  IllegalArgumentException with message "email must not be null".
  Change nothing else.

The more specific and constrained the prompt, the more likely Claude does exactly what you want.

Mistake 8: Refactoring Without Tests

What happens: You ask Claude to “clean up this module.” Claude restructures the code. The restructured code looks better but has subtly different behavior. No tests catch the regression.

Why it happens: Refactoring changes structure, and sometimes accidentally changes behavior. Without tests, there’s no safety net.

How to fix it: Always write tests first:

> Before we refactor, write characterization tests that capture the
  current behavior of this module. Test all code paths with specific
  assertions on the output.

Then refactor:

> Now extract the formatting logic. All the tests we just wrote must
  still pass.

Mistake 9: Using Claude Like Stack Overflow

What happens: You ask “how do I mock a database in JUnit?” Claude gives you a generic answer about Mockito. But it could have given you a working test for YOUR specific service if you’d asked differently.

Why it happens: Old habits. When you’ve spent years searching Google and Stack Overflow, you default to asking for information instead of asking for action.

How to fix it: Ask for what you actually want:

> Write a test for UserRegistrationService.register() that mocks the
  UserRepository to return true for existsByUsername("taken")

Claude has your project context. Use it.

Mistake 10: Not Configuring Permissions

What happens: Claude asks for permission to run ./gradlew test every single time. After the 10th confirmation, you stop paying attention and auto-approve. This defeats the purpose of permissions.

Why it happens: Default permissions require approval for every shell command. For safe, repetitive commands like test runners, this creates friction without value.

How to fix it: Add safe commands to .claude/settings.json:

{
  "permissions": {
    "allow": [
      "Bash(./gradlew test*)",
      "Bash(npm test*)",
      "Bash(bundle exec rspec*)",
      "Bash(git diff*)",
      "Bash(git status*)",
      "Bash(git log*)"
    ]
  }
}

Now Claude runs tests automatically, and you still get prompted for commands that could modify files or access external systems.


Recovery Cheat Sheet

SituationRecovery
Committed code I didn’t reviewgit diff HEAD~1 to see what changed, audit it now
Claude changed more than I askedgit checkout -- <file> to revert, retry with tighter prompt
Tests pass but test the wrong thingAsk: “What bug would this test catch?” — rewrite if answer is “nothing specific”
Refactoring broke somethinggit revert HEAD to undo, add tests first, then retry
Claude is confused / stuck/clear and start fresh with a specific, constrained prompt
Generated code has security issuesReview with: “Check this code for OWASP Top 10 vulnerabilities”
Feature is half-built and messyCommit what works, /clear, plan the remaining pieces