Back to catalog

bug-fixer-diagnostic

Advanced diagnostic workflow for bug-fixer agent with mandatory Context7 MCP consultations, Chrome DevTools MCP integration, and systematic root cause analysis across all Clean Architecture layers.

  • Category: discovered
  • Tags: github, community
  • Version: 1.0.0
  • Author: walid
  • Downloads: 0
  • Updated: 2025-11-22

Download the latest version (v1.0.0) from this page.

SKILL.md

---
name: bug-fixer-diagnostic
description: Advanced diagnostic workflow for bug-fixer agent with mandatory Context7 MCP consultations, Chrome DevTools MCP integration, and systematic root cause analysis across all Clean Architecture layers.
---

# Bug Fixer Diagnostic Skill

**Purpose**: Provide systematic debugging workflow with mandatory Context7 consultations and MCP tool integration for diagnosing and fixing bugs in production code.

---

## 🎯 CORE DEBUGGING PRINCIPLES

### Debugging Philosophy
- **Research First**: ALWAYS consult Context7 before implementing fixes
- **Root Cause Over Symptoms**: Never apply band-aid fixes
- **Minimal Changes**: Surgical fixes only, no refactoring
- **Verification Required**: ALL tests must pass after fix
- **Tools Are Mandatory**: Use MCPs (Chrome DevTools, Supabase) for diagnosis

### When NOT to Use This Skill
- ❌ Adding new features → Use Architect → TDD flow
- ❌ Large refactorings → Discuss with user first
- ❌ Performance optimization → Use separate optimization workflow
- ❌ Code cleanup → Not a bug, suggest improvements only

---

## 📋 4-PHASE DEBUGGING WORKFLOW

### PHASE 0: Bug Classification & Triage

**Objective**: Understand the bug and classify it for appropriate debugging strategy.

#### Step 0.1: Extract Bug Information

**Questions to answer**:
1. **Symptoms**: What is the observable error?
   - Exact error message/stack trace
   - Expected vs actual behavior
   - Frequency (always, intermittent, specific conditions)

2. **Context**: Where does it occur?
   - Which layer? (UI, API, use case, service, database, E2E test)
   - Which file/function?
   - Which environment? (local, staging, production)

3. **Impact**: How severe?
   - Blocking users completely?
   - Data corruption risk?
   - Intermittent/flaky?
   - Visual only?

4. **Reproduction**: Can you reproduce it?
   - Steps to reproduce
   - Consistency (100%, 50%, rare)
   - User role/permissions needed

#### Step 0.2: Classify Bug Type

**Bug categories** (determines debugging strategy):

**1. Validation Bug** (Zod schema issue)
- Symptoms: Validation errors, safeParse failures, type mismatches
- Tools: Context7 for Zod patterns
- Reference: `references/zod-validation.md`

**2. Database Bug** (Supabase/RLS issue)
- Symptoms: Data not appearing, RLS blocks, query errors
- Tools: Supabase MCP to query state, Context7 for RLS patterns
- Reference: `references/supabase-rls.md`

**3. UI Bug** (React/Next.js issue)
- Symptoms: Hydration errors, visual glitches, interaction failures
- Tools: Chrome DevTools MCP, Context7 for React/Next.js
- Reference: `references/nextjs-errors.md`, `references/react-debugging.md`

**4. E2E Bug** (Playwright test failure)
- Symptoms: Test failures, selector issues, timeouts, flaky tests
- Tools: Playwright debugger with --debug, Chrome DevTools MCP
- Reference: `references/playwright-debugging.md`

**5. Integration Bug** (Layer boundary issue)
- Symptoms: Type mismatches, data transformation errors
- Tools: Read relevant files, trace data flow
- Strategy: Check entity schemas, service interfaces, API contracts

**6. Performance Bug** (Slow queries, memory leaks)
- Symptoms: Timeouts, high memory usage, slow responses
- Tools: Supabase advisors, Chrome DevTools performance tab
- Note: May need separate performance optimization workflow

**7. Authorization Bug** (CASL/RLS permission issue)
- Symptoms: UI elements visible but API returns 403, elements hidden when user should have access, "Permission denied" errors
- Tools: Chrome DevTools console for ability inspection, Supabase MCP for RLS testing, Context7 for CASL patterns
- Strategy: Verify CASL + RLS alignment, check ability loading, test permission mapping
- Reference: See **CASL Authorization Debugging** section below

**Deliverable**: Bug classification and initial diagnosis notes

---

### PHASE 1: Deep Diagnosis (RESEARCH FIRST!)

**Objective**: Identify root cause through systematic investigation with Context7 guidance.

**⚠️ MANDATORY**: Never skip Context7 consultation for your bug type.

#### Step 1.1: Context7 Research (ALWAYS FIRST)

**Why Context7 is mandatory**:
- Training data may be outdated
- Breaking changes in library versions
- New best practices emerge
- Known issues and workarounds

**Bug-specific Context7 queries**:

```typescript
// For Validation Bugs (Zod)
await context7.get_library_docs({
  context7CompatibleLibraryID: "/colinhacks/zod",
  topic: "safeParse error handling issues flatten custom errors debugging",
  tokens: 3000
})

// For Database Bugs (Supabase RLS)
await context7.get_library_docs({
  context7CompatibleLibraryID: "/supabase/supabase",
  topic: "RLS policies debugging circular errors authentication performance",
  tokens: 3000
})

// For UI Bugs (Next.js)
await context7.get_library_docs({
  context7CompatibleLibraryID: "/vercel/next.js",
  topic: "server components hydration errors client boundaries debugging",
  tokens: 2500
})

// For UI Bugs (React)
await context7.get_library_docs({
  context7CompatibleLibraryID: "/facebook/react",
  topic: "hooks dependencies useEffect memory leaks debugging",
  tokens: 2500
})

// For Authorization Bugs (CASL)
await context7.get_library_docs({
  context7CompatibleLibraryID: "/stalniy/casl",
  topic: "ability can cannot conditions debugging rules checking",
  tokens: 2500
})

// For E2E Bugs (Playwright)
await context7.get_library_docs({
  context7CompatibleLibraryID: "/microsoft/playwright",
  topic: "debugging test failures selectors wait for timeout race conditions",
  tokens: 3000
})

// For Unit Test Bugs (Vitest)
await context7.get_library_docs({
  context7CompatibleLibraryID: "/vitest-dev/vitest",
  topic: "debugging test failures error handling mock issues async",
  tokens: 3000
})
```

**Review Context7 output for**:
- ✅ Latest error handling patterns
- ✅ Known issues and workarounds
- ✅ Best practices for this specific case
- ✅ Breaking changes in recent versions
- ✅ Common mistakes to avoid

#### Step 1.2: Layer-Specific Diagnosis

**For Validation Bugs (Entities/Zod)**:

```typescript
// 1. Read the problematic schema
const entityFile = await Read('app/src/features/[feature]/entities.ts')

// 2. Check usage in use cases - look for .parse() vs .safeParse()
await Grep({
  pattern: "EntitySchema\\.parse",
  path: "app/src/features/[feature]/use-cases",
  output_mode: "content",
  "-n": true
})

// 3. Common issues to check:
// ❌ Using .parse() instead of .safeParse()? (throws instead of returning result)
// ❌ Error messages not clear?
// ❌ Refinement logic incorrect?
// ❌ Type mismatch between schema and usage?
```

**Best practices from Context7**:
- ✅ Always use `.safeParse()` for controllable error handling
- ✅ Use `.flatten()` on errors for better structure
- ✅ Create schemas inside components for translation access
- ✅ Check for circular refinements

**For Database Bugs (Services/Supabase)**:

```typescript
// 1. Query actual database state
const data = await supabase.execute_sql({
  query: `SELECT * FROM [table] WHERE [condition]`
})

// 2. Check RLS policies
const policies = await supabase.execute_sql({
  query: `SELECT * FROM pg_policies WHERE tablename = '[table]'`
})

// 3. Test RLS with specific user context
await supabase.execute_sql({
  query: `
    SET LOCAL ROLE authenticated;
    SET LOCAL request.jwt.claims.sub = '[test-user-id]';
    SELECT * FROM [table];  -- Should return expected data
  `
})

// 4. Check for circular policy references (common issue)
// Look for policies that reference the same table they're applied to

// 5. Check logs for errors
const logs = await supabase.get_logs({
  project_id: "project-id",
  service: "postgres"
})

// 6. Run security advisors
const advisors = await supabase.get_advisors({
  project_id: "project-id",
  type: "security"
})
```

**Common RLS issues** (from Context7):
- ❌ Circular policies (policy references same table)
- ❌ Missing auth.uid() checks
- ❌ Not scoping to authenticated role (TO authenticated)
- ❌ Complex joins in RLS (performance killer)

**Best practice** (from Context7):
```sql
-- ✅ GOOD: No circular reference
CREATE POLICY "access_policy" ON tasks
  FOR SELECT
  TO authenticated
  USING (
    organization_id IN (
      SELECT organization_id
      FROM user_organizations
      WHERE user_id = (SELECT auth.uid())  -- No join back to tasks!
    )
  );

-- ❌ BAD: Circular reference
CREATE POLICY "bad_policy" ON tasks
  FOR SELECT
  USING (
    auth.uid() IN (
      SELECT user_id FROM team_user
      WHERE team_user.team_id = tasks.team_id  -- CIRCULAR! References tasks
    )
  );
```

**For UI Bugs (Components/React)**:

```typescript
// 1. Use Chrome DevTools MCP to inspect live state
await mcp__chrome_devtools__new_page()
await mcp__chrome_devtools__navigate_page({
  url: "http://localhost:3000/problematic-page"
})

// 2. Take snapshot for visual inspection
const snapshot = await mcp__chrome_devtools__take_snapshot()

// 3. Evaluate JavaScript to check state
const state = await mcp__chrome_devtools__evaluate_script({
  script: `
    return {
      errors: document.querySelector('.error')?.textContent,
      consoleErrors: [...console.memory || []],
      hydrationErrors: window.__NEXT_DATA__?.props?.pageProps?.errors
    }
  `
})

// 4. Check for hydration mismatches (Next.js specific)
// Look for console warnings: "Hydration failed because..."
// Common cause: Server/client render different content

// 5. Consult Context7 for React patterns
await context7.get_library_docs({
  context7CompatibleLibraryID: "/facebook/react",
  topic: "hooks useEffect dependencies errors hydration debugging",
  tokens: 2500
})
```

**Common React/Next.js issues** (from Context7):
- ❌ useEffect missing dependencies
- ❌ Server/client rendering mismatch (hydration error)
- ❌ Race conditions (component unmounts before async completes)
- ❌ Incorrect 'use client' directive placement

**Best practices from Context7**:
```typescript
// ✅ Cleanup on unmount to prevent race conditions
useEffect(() => {
  let cancelled = false

  fetchData().then(result => {
    if (!cancelled) setData(result)
  })

  return () => { cancelled = true }
}, [])

// ❌ Race condition - no cleanup
useEffect(() => {
  fetchData().then(setData) // Fails if component unmounts!
}, [])
```

**For E2E Test Failures (Playwright)**:

```bash
# 1. Run with Playwright Inspector for step-through debugging
npx playwright test failing-test.spec.ts:42 --debug

# 2. Run with verbose API logs
DEBUG=pw:api npx playwright test failing-test.spec.ts

# 3. Generate trace for analysis
npx playwright test failing-test.spec.ts --trace on

# 4. View trace after failure
npx playwright show-trace trace.zip

# 5. Run in UI mode for interactive debugging
npx playwright test --ui
```

```typescript
// Use Chrome DevTools MCP for live inspection
await mcp__chrome_devtools__new_page()
await mcp__chrome_devtools__navigate_page({
  url: "http://localhost:3000/test-page"
})

// Wait for problematic element
await mcp__chrome_devtools__wait_for({
  selector: ".expected-element",
  timeout: 5000
})

// Take screenshot of current state
await mcp__chrome_devtools__take_screenshot()
```

**Common Playwright issues** (from Context7):
- ❌ Using brittle CSS selectors (`.button.primary.large`)
- ❌ Not using web-first assertions (`toBeVisible()`)
- ❌ Manual checks instead of automatic retries
- ❌ Race conditions with async content

**Best practices from Context7**:
```typescript
// ✅ GOOD: Web-first assertion (auto-retries)
await expect(page.getByText('welcome')).toBeVisible()

// ❌ BAD: Manual check (no retry)
expect(await page.getByText('welcome').isVisible()).toBe(true)

// ✅ GOOD: Semantic selector (robust)
await page.getByRole('button', { name: 'Submit' })

// ❌ BAD: Brittle CSS selector
await page.click('.btn-primary-submit-form-action')
```

#### Step 1.3: Root Cause Identification

**Document findings**:

```markdown
## Root Cause Analysis

**Bug Type**: [Validation/Database/UI/E2E/Integration/Performance]

**Layer Affected**: [Entities/Use Cases/Services/Components/E2E]

**Root Cause**:
[Clear explanation of WHY the bug occurs, not just what]

**Evidence**:
1. [Finding from Context7 documentation]
2. [Finding from Chrome DevTools inspection]
3. [Finding from Supabase query]
4. [Finding from Playwright debugger]
5. [Finding from code analysis]

**Why It Wasn't Caught**:
- Missing test coverage?
- Edge case not considered?
- Environment-specific issue?
- Timing/race condition?

**Impact Scope**:
- Which users affected?
- Which features broken?
- Data integrity risk?
```

**Deliverable**: Complete root cause analysis document

---

### PHASE 2: Research-Driven Fix Implementation

**Objective**: Apply minimal, targeted fix using latest patterns from Context7.

**⚠️ CRITICAL**: Only fix AFTER understanding root cause and verifying latest patterns.

#### Step 2.1: Verify Latest Fix Patterns (Context7)

```typescript
// NEVER use outdated patterns from training data
// ALWAYS verify latest approach with Context7

// Example: Fixing Zod validation
await context7.get_library_docs({
  context7CompatibleLibraryID: "/colinhacks/zod",
  topic: "safeParse error handling best practices latest version",
  tokens: 2000
})

// Review to ensure fix follows:
// ✅ Latest API patterns
// ✅ Recommended best practices
// ✅ No deprecated methods
// ✅ Optimal performance approach
```

#### Step 2.2: Implement Minimal Fix

**Principle**: Make the SMALLEST change that fixes the root cause.

**Example Fix Patterns** (validated with Context7):

**Validation Bug Fix**:
```typescript
// ❌ BEFORE (using .parse - throws)
export async function createEntity(input: unknown) {
  const validated = EntityCreateSchema.parse(input) // Throws!
  return service.create(validated)
}

// ✅ AFTER (using .safeParse - returns result)
export async function createEntity(input: unknown) {
  const result = EntityCreateSchema.safeParse(input)

  if (!result.success) {
    // Use flatten() for better error structure (Context7 pattern)
    const errors = result.error.flatten()
    throw new ValidationError('Invalid input', errors)
  }

  return service.create(result.data)
}
```

**RLS Policy Bug Fix**:
```sql
-- ❌ BEFORE (circular policy - slow!)
CREATE POLICY "bad_policy" ON tasks
  FOR SELECT
  USING (
    auth.uid() IN (
      SELECT user_id FROM team_user
      WHERE team_user.team_id = tasks.team_id  -- CIRCULAR!
    )
  );

-- ✅ AFTER (no circular reference - fast!)
CREATE POLICY "fixed_policy" ON tasks
  FOR SELECT
  TO authenticated
  USING (
    organization_id IN (
      SELECT organization_id
      FROM user_organizations
      WHERE user_id = (SELECT auth.uid())  -- No join to tasks!
    )
  );
```

**UI Race Condition Fix**:
```typescript
// ❌ BEFORE (race condition)
export function Component() {
  const [data, setData] = useState(null)

  useEffect(() => {
    fetchData().then(setData) // Race condition if component unmounts!
  }, [])

  return <div>{data?.name}</div>
}

// ✅ AFTER (cleanup on unmount - Context7 pattern)
export function Component() {
  const [data, setData] = useState(null)

  useEffect(() => {
    let cancelled = false

    fetchData().then(result => {
      if (!cancelled) setData(result)
    })

    return () => { cancelled = true }
  }, [])

  return <div>{data?.name}</div>
}
```

**E2E Test Selector Fix**:
```typescript
// ❌ BEFORE (brittle selector - Context7 anti-pattern)
await page.click('.button-primary') // Breaks if CSS changes

// ✅ AFTER (semantic selector - Context7 best practice)
await page.getByRole('button', { name: 'Submit' }) // Robust

// OR (data-testid - also recommended)
await page.click('[data-testid="submit-button"]') // Explicit test hook
```

#### Step 2.3: Add Defensive Error Handling

If bug was caused by missing error handling, add proper guards:

```typescript
// Add null checks
if (!user) {
  throw new NotFoundError('User not found')
}

// Add type guards
if (typeof data.email !== 'string') {
  throw new ValidationError('Email must be a string')
}

// Add try-catch for external calls
try {
  await externalApi.call()
} catch (error) {
  logger.error('External API failed', { error })
  throw new IntegrationError('Failed to contact external service', { cause: error })
}
```

**Deliverable**: Implemented fix with defensive guards

---

### PHASE 3: Comprehensive Verification

**Objective**: Ensure fix works and no regressions introduced.

**⚠️ CRITICAL**: NEVER consider a bug fixed until ALL verification passes.

#### Step 3.1: Run Affected Tests

```bash
# 1. Run unit tests for affected layer
npm run test app/src/features/[feature]/

# 2. Run integration tests
npm run test app/src/app/api/[feature]/

# 3. Run ALL E2E tests (regression check)
npm run test:e2e

# 4. Run type checking
npm run typecheck

# 5. Run linting
npm run lint
```

**All tests must pass**. If any fail:
- Investigate if test revealed another bug
- Fix the newly discovered bug
- Re-run full test suite

#### Step 3.2: Manual Verification

**For UI bugs**:
```typescript
// 1. Use Chrome DevTools MCP to verify fix
await mcp__chrome_devtools__new_page()
await mcp__chrome_devtools__navigate_page({
  url: "http://localhost:3000/fixed-page"
})

// 2. Reproduce original bug scenario
await mcp__chrome_devtools__click({ selector: "button" })

// 3. Verify fix worked
const state = await mcp__chrome_devtools__evaluate_script({
  script: "return document.querySelector('.error') === null"
})

// 4. Take screenshot for comparison
await mcp__chrome_devtools__take_screenshot()
```

**For database bugs**:
```typescript
// 1. Verify RLS policy works correctly
await supabase.execute_sql({
  query: `
    SET LOCAL ROLE authenticated;
    SET LOCAL request.jwt.claims.sub = '[test-user-id]';
    SELECT * FROM tasks;  -- Should only return user's tasks
  `
})

// 2. Check security advisors again
await supabase.get_advisors({
  project_id: "project-id",
  type: "security"
})
```

**For E2E bugs**:
```bash
# 1. Run fixed test in debug mode
npx playwright test fixed-test.spec.ts --debug

# 2. Run in UI mode to visually verify
npx playwright test fixed-test.spec.ts --ui

# 3. Run multiple times to check for flakiness
for i in {1..10}; do npx playwright test fixed-test.spec.ts; done
```

#### Step 3.3: Regression Check

**Verify no new issues**:

1. **Run FULL Test Suite**:
   ```bash
   npm run test
   npm run test:e2e
   ```

2. **Check All Affected Flows**:
   - If you fixed validation, test ALL CRUD operations
   - If you fixed RLS, test with different user roles
   - If you fixed UI, test on different browsers/devices

3. **Performance Check**:
   - Did fix introduce performance regression?
   - Use Chrome DevTools Performance tab
   - Use Supabase EXPLAIN ANALYZE for queries

4. **Security Check**:
   - Did fix introduce security vulnerability?
   - Run Supabase security advisors
   - Verify RLS still enforces isolation

**Deliverable**: All tests passing, no regressions detected

---

### PHASE 4: Documentation & Prevention

**Objective**: Document fix and recommend preventive measures.

#### Step 4.1: Document the Fix

```markdown
## Bug Fix Report

**Bug ID**: [Reference to issue/ticket if applicable]

**Summary**: [One sentence description]

**Root Cause**:
[Detailed explanation of why bug occurred]

**Files Changed**:
- `path/to/file1.ts` (Lines X-Y)
- `path/to/file2.ts` (Lines X-Y)

**Fix Applied**:
[Explanation of what was changed and why]

**Research Sources**:
- Context7: [Library and topic searched]
- Chrome DevTools: [Findings from inspection]
- Supabase: [Database queries/logs reviewed]
- Playwright: [Debugging commands used]

**Verification**:
- ✅ Unit tests passing
- ✅ Integration tests passing
- ✅ E2E tests passing
- ✅ Manual testing completed
- ✅ No regression detected

**Prevention**:
[How to prevent this bug in future]
- [ ] Add missing test coverage?
- [ ] Update validation schema?
- [ ] Improve error messages?
- [ ] Add documentation?
```

#### Step 4.2: Suggest Preventive Measures

**