Bug Fixing Guide
This guide covers the systematic approach to fixing bugs using Claude-Craft, from diagnosis to validation.
Table of Contents
- Bug Fixing Workflow
- Phase 1: Reproduce
- Phase 2: Diagnose
- Phase 3: Write Regression Test
- Phase 4: Fix
- Phase 5: Validate
- Phase 6: Document
- Hotfix Procedures
- Complete Example
Bug Fixing Workflow
The systematic approach to fixing bugs:
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ 1. Reproduce│ --> │ 2. Diagnose │ --> │ 3. Test │
└─────────────┘ └─────────────┘ └─────────────┘
│
v
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ 6. Document │ <-- │ 5. Validate │ <-- │ 4. Fix │
└─────────────┘ └─────────────┘ └─────────────┘Why This Approach?
- Reproduce first: Can't fix what you can't see
- Test before fix: Proves the bug exists and is fixed
- Validate thoroughly: Ensures no regression
- Document: Helps prevent similar bugs
Phase 1: Reproduce
Before fixing, consistently reproduce the bug.
Gather Information
Collect from bug report:
- Steps to reproduce
- Expected behavior
- Actual behavior
- Environment (version, OS, etc.)
- Error messages/logs
- Screenshots if applicable
Create Reproduction Environment
bash
# Check out the problematic version
git checkout <commit-or-tag>
# Set up identical environment
make docker-up
# Reproduce with exact stepsVerify Reproduction
Can you trigger the bug consistently?
- [ ] Bug occurs with reported steps
- [ ] Bug occurs in same environment
- [ ] Bug is deterministic (not random)
If You Can't Reproduce
markdown
@research-assistant Help me understand why this bug might be environment-specific
Bug report:
- User sees error X when doing Y
- I cannot reproduce locally
- User is on environment Z
Possible causes?Phase 2: Diagnose
Find the root cause of the bug.
Using Analysis Command
bash
/common:analyze-bug "Users cannot login with correct credentials after password reset"This command will:
- Suggest areas to investigate
- Identify potential causes
- Recommend debugging steps
- List related code areas
Using TDD Coach for Diagnosis
markdown
@tdd-coach Help me diagnose this authentication bug
Symptoms:
- User resets password successfully
- New password is saved (confirmed in DB)
- Login fails with "invalid credentials"
- Old password also doesn't work
What should I investigate?Debugging Techniques
Add Logging
php
// Temporary debug logging
$this->logger->debug('Password verification', [
'user_id' => $user->getId(),
'stored_hash' => substr($user->getPasswordHash(), 0, 20) . '...',
'verification_result' => $result,
]);Inspect Database State
sql
-- Check user state after password reset
SELECT id, email, password_hash, updated_at
FROM users
WHERE email = 'user@example.com';Trace Execution Path
php
// Add stack trace at suspicious points
debug_print_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);Identify Root Cause
Common categories:
- Logic error: Wrong condition or calculation
- State error: Incorrect data state
- Race condition: Timing-dependent behavior
- Integration error: External service issue
- Configuration error: Wrong settings
Diagnosis Checklist
- [ ] Bug consistently reproduced
- [ ] Error location identified
- [ ] Root cause understood
- [ ] Related code areas identified
- [ ] Fix approach determined
Phase 3: Write Regression Test
Write a test that fails BEFORE the fix and passes AFTER.
Why Test First?
- Proves bug exists: Test fails with current code
- Proves fix works: Test passes after fix
- Prevents regression: Test catches future breaks
- Documents behavior: Test describes expected behavior
Using TDD Coach
markdown
@tdd-coach Help me write a regression test for this bug
Bug: Password reset doesn't update the password hash correctly
Expected behavior:
- User requests password reset
- User sets new password
- User can login with new password
Actual behavior:
- Login fails after password resetExample Regression Test
php
/**
* @test
* @see https://github.com/company/project/issues/123
*
* Bug: Users could not login after password reset
* Root cause: Password hash was not persisted correctly
*/
public function test_user_can_login_after_password_reset(): void
{
// Arrange: Create user with known password
$user = $this->createUser('user@example.com', 'old-password');
// Act: Reset password
$this->passwordResetService->resetPassword($user, 'new-password');
// Assert: Can login with new password
$result = $this->authService->authenticate('user@example.com', 'new-password');
$this->assertTrue($result->isSuccess());
$this->assertNotNull($result->getToken());
}
/**
* @test
* Related: Ensure old password no longer works
*/
public function test_old_password_fails_after_reset(): void
{
$user = $this->createUser('user@example.com', 'old-password');
$this->passwordResetService->resetPassword($user, 'new-password');
$result = $this->authService->authenticate('user@example.com', 'old-password');
$this->assertFalse($result->isSuccess());
}Test Writing Checklist
- [ ] Test reproduces the bug (fails before fix)
- [ ] Test has descriptive name
- [ ] Test references issue number
- [ ] Test documents root cause in comment
- [ ] Related edge cases tested
Phase 4: Fix
Implement the minimal fix for the bug.
Fix Guidelines
- Minimal change: Fix only the bug, don't refactor
- Clear intent: Code should show what was wrong
- No side effects: Don't change unrelated behavior
- Maintain style: Match existing code patterns
Example Fix
php
// BEFORE (buggy)
public function resetPassword(User $user, string $newPassword): void
{
$hash = $this->hasher->hash($newPassword);
$user->setPasswordHash($hash);
// Bug: Missing persist/flush!
}
// AFTER (fixed)
public function resetPassword(User $user, string $newPassword): void
{
$hash = $this->hasher->hash($newPassword);
$user->setPasswordHash($hash);
$this->entityManager->persist($user); // <-- Fix
$this->entityManager->flush(); // <-- Fix
}Run the Regression Test
bash
# Test should now pass
make test-unit TEST=tests/Unit/PasswordResetTest.php
# Or run specific test
./vendor/bin/phpunit --filter test_user_can_login_after_password_resetFix Checklist
- [ ] Regression test now passes
- [ ] Fix is minimal and focused
- [ ] No unrelated changes included
- [ ] Code style maintained
Phase 5: Validate
Ensure the fix doesn't break anything else.
Run Full Test Suite
bash
# All unit tests
make test-unit
# All integration tests
make test-integration
# Full test suite
make testQuality Checks
bash
# Code quality (per technology)
/symfony:check-code-quality
/flutter:check-code-quality
/python:check-code-quality
# Security (if fix touches sensitive code)
/common:security-audit
# Full compliance
/symfony:check-complianceManual Testing
Even with automated tests, verify manually:
- Follow original bug reproduction steps
- Verify bug no longer occurs
- Test related functionality
- Check edge cases
Using Reviewer Agent
markdown
@symfony-reviewer Review my bug fix for issue #123
Bug: Users couldn't login after password reset
Fix: Added missing persist/flush in resetPassword()
Changed files:
- src/Application/Service/PasswordResetService.php
- tests/Unit/PasswordResetTest.php
Please check:
1. Fix is correct and complete
2. No side effects
3. Test coverage adequateValidation Checklist
- [ ] Regression test passes
- [ ] All existing tests pass
- [ ] Static analysis passes
- [ ] Manual testing confirms fix
- [ ] Code review completed
Phase 6: Document
Document the fix for future reference.
Commit Message Format
fix(auth): resolve login failure after password reset
Bug: Users could not login after resetting their password
Root cause: Password hash change was not persisted to database
Fix: Added persist() and flush() calls in PasswordResetService
Closes #123
Test: test_user_can_login_after_password_resetUpdate Issue Tracker
markdown
## Resolution
**Root Cause:**
The `resetPassword()` method in `PasswordResetService` was updating the user's
password hash in memory but not persisting the change to the database.
**Fix:**
Added `persist()` and `flush()` calls after setting the new password hash.
**Testing:**
- Added regression test `test_user_can_login_after_password_reset`
- Added edge case test `test_old_password_fails_after_reset`
**Prevention:**
Consider adding a code review checklist item for persistence operations.Knowledge Base Entry (if recurring pattern)
markdown
# Common Bug: Entity Changes Not Persisted
## Symptoms
- Data changes appear to work (no errors)
- Changes don't appear in database
- Changes lost after refresh
## Root Cause
Missing `persist()` and/or `flush()` calls in Doctrine.
## Fix Pattern
```php
$entity->setSomething($value);
$this->entityManager->persist($entity); // Don't forget!
$this->entityManager->flush();Prevention
- Add persistence check to code review checklist
- Consider auto-flush in service base class
### Documentation Checklist
- [ ] Commit message describes bug and fix
- [ ] Issue tracker updated with resolution
- [ ] Related documentation updated
- [ ] Knowledge base entry if pattern
---
## Hotfix Procedures
For critical bugs in production.
### Hotfix Workflow- Create hotfix branch from production
- Apply minimal fix
- Test thoroughly
- Deploy to production
- Merge back to main
### Step-by-Step
```bash
# 1. Create hotfix branch
git checkout production
git checkout -b hotfix/issue-123-login-failure
# 2. Apply fix
# ... make changes ...
# 3. Write regression test
# ... add test ...
# 4. Verify
make test
/symfony:check-compliance
# 5. Commit with clear message
git commit -m "fix(auth): resolve critical login failure after password reset
HOTFIX for production issue.
Root cause: Password hash not persisted after reset.
Closes #123"
# 6. Create PR for review
gh pr create --base production --title "HOTFIX: Login failure after password reset"
# 7. After merge, deploy
# ... deployment process ...
# 8. Merge back to main
git checkout main
git merge hotfix/issue-123-login-failure
git push origin mainHotfix Checklist
- [ ] Hotfix branch from production
- [ ] Minimal, focused fix only
- [ ] Regression test added
- [ ] All tests passing
- [ ] PR reviewed and approved
- [ ] Deployed to production
- [ ] Verified in production
- [ ] Merged back to main
Complete Example
Let's walk through fixing a real bug.
Bug Report
Issue #456: Order total calculated incorrectly
Steps to reproduce:
1. Add item with price $10.00, quantity 3
2. Add item with price $5.50, quantity 2
3. View cart
Expected: Total = $41.00 (30 + 11)
Actual: Total = $36.00
Environment: Production v2.3.1
Reported by: Customer support
Priority: HighStep 1: Reproduce
php
// Quick local test
$order = new Order();
$order->addItem(new Item('A', 10.00), 3); // $30
$order->addItem(new Item('B', 5.50), 2); // $11
echo $order->getTotal(); // Shows 36.00 - confirmed!Step 2: Diagnose
markdown
@tdd-coach Help me find the bug in order total calculation
The total should be 41.00 but shows 36.00
Difference is 5.00, which is exactly one of item B's price
Hypothesis: quantity for second item not being counted?Investigation reveals:
php
// Bug found in Order::calculateTotal()
public function calculateTotal(): Money
{
$total = Money::zero();
foreach ($this->items as $item) {
// BUG: Using 1 instead of item quantity!
$total = $total->add($item->getPrice()->multiply(1));
}
return $total;
}Step 3: Write Regression Test
php
/**
* @test
* @see https://github.com/company/shop/issues/456
*
* Bug: Order total ignored item quantities
*/
public function test_order_total_includes_all_quantities(): void
{
$order = new Order();
$order->addItem($this->createItem(10.00), 3); // $30
$order->addItem($this->createItem(5.50), 2); // $11
$total = $order->calculateTotal();
$this->assertEquals(41.00, $total->getAmount());
}
/**
* @test
* Edge case: single item with quantity > 1
*/
public function test_single_item_quantity_multiplied(): void
{
$order = new Order();
$order->addItem($this->createItem(10.00), 5);
$this->assertEquals(50.00, $order->calculateTotal()->getAmount());
}Run test - confirms it fails.
Step 4: Fix
php
public function calculateTotal(): Money
{
$total = Money::zero();
foreach ($this->items as $item) {
// Fixed: Use actual quantity from order item
$total = $total->add(
$item->getPrice()->multiply($item->getQuantity())
);
}
return $total;
}Step 5: Validate
bash
# Regression test passes
./vendor/bin/phpunit --filter test_order_total
# All tests pass
make test
# Quality check
/symfony:check-compliance
# Score: 94/100 ✓Step 6: Document
bash
git commit -m "fix(order): correct total calculation to include quantities
Bug: Order total was ignoring item quantities, always using 1
Root cause: Hardcoded multiply(1) instead of multiply(quantity)
Fix: Use getQuantity() from order item in calculation
Closes #456
Regression tests added:
- test_order_total_includes_all_quantities
- test_single_item_quantity_multiplied"Bug Prevention Tips
- Write tests first: TDD prevents many bugs
- Code review: Fresh eyes catch issues
- Static analysis: Tools find common errors
- Integration tests: Catch interaction bugs
- Monitor production: Catch issues early
