Root cause analysis methods for PHP bugs. Provides 5 Whys technique, fault tree analysis, git bisect guidance, and stack trace parsing.
From accnpx claudepluginhub dykyi-roman/awesome-claude-code --plugin accThis skill uses the workspace's default tool permissions.
Systematic methods for finding the true source of bugs, not just symptoms.
The location where an error manifests is rarely where the bug originates.
Error Location: OrderController::show() - NullPointerException
Symptom Location: OrderRepository::find() - returns null
Root Cause: OrderCreatedHandler - failed to persist order
True Root Cause: RabbitMQ message lost due to missing ACK
Ask "why" repeatedly until you reach the root cause.
Bug: "Customer sees wrong order total"
Order::getTotal() returns 0OrderItem collection is emptyRoot Cause: EntityManager closed before accessing lazy-loaded collection
Fix: Eager load items in repository query, not lazy load
## 5 Whys Analysis
**Bug Description:** [What user sees]
1. Why does [symptom] occur?
→ [First-level cause]
2. Why does [first-level cause] happen?
→ [Second-level cause]
3. Why does [second-level cause] happen?
→ [Third-level cause]
4. Why does [third-level cause] happen?
→ [Fourth-level cause]
5. Why does [fourth-level cause] happen?
→ [ROOT CAUSE]
**Fix Location:** [File:line where fix should be applied]
**Fix Type:** [Category: logic/null/boundary/race/resource/exception/type/sql/infinite]
Build a tree of all possible causes for a failure.
[FAILURE: Order total is $0]
│
├── [OR] Order has no items
│ ├── [AND] Items not added during creation
│ │ ├── Cart was empty
│ │ └── Cart-to-Order mapping failed
│ │
│ └── [AND] Items were deleted
│ ├── Cascade delete triggered
│ └── Manual deletion bug
│
└── [OR] Items exist but total calculation wrong
├── Price is 0
│ ├── Product price not set
│ └── Currency conversion failed
│
└── Quantity is 0
├── Validation missing
└── Type coercion (string "0")
Find the exact commit that introduced a bug.
# 1. Start bisect
git bisect start
# 2. Mark current (broken) as bad
git bisect bad
# 3. Mark known good commit (e.g., last release)
git bisect good v2.3.0
# 4. Git checks out middle commit - test it
# Run your reproduction test
php artisan test --filter=OrderTotalTest
# 5. Mark result
git bisect good # if test passes
git bisect bad # if test fails
# 6. Repeat until Git finds the culprit commit
# Git will output: "abc123 is the first bad commit"
# 7. Examine the commit
git show abc123
# 8. End bisect
git bisect reset
# Run automatically with test script
git bisect start HEAD v2.3.0
git bisect run php artisan test --filter=OrderTotalTest
Extract actionable information from error traces.
Fatal error: Uncaught TypeError: OrderService::calculateTotal():
Argument #1 ($items) must be of type array, null given,
called in /app/src/Application/UseCase/CreateOrderUseCase.php on line 45
Stack trace:
#0 /app/src/Application/UseCase/CreateOrderUseCase.php(45): OrderService->calculateTotal(NULL)
#1 /app/src/Presentation/Api/OrderController.php(32): CreateOrderUseCase->execute(Object(CreateOrderCommand))
#2 /app/vendor/symfony/http-kernel/HttpKernel.php(163): OrderController->create(Object(Request))
#3 /app/vendor/symfony/http-kernel/HttpKernel.php(75): HttpKernel->handleRaw(Object(Request))
#4 /app/public/index.php(25): HttpKernel->handle(Object(Request))
#5 {main}
thrown in /app/src/Domain/Service/OrderService.php on line 23
| Element | Value | Meaning |
|---|---|---|
| Error Type | TypeError | Type mismatch bug |
| Message | Argument #1 must be array, null given | Null pointer issue |
| Thrown Location | OrderService.php:23 | Where error detected |
| Call Location | CreateOrderUseCase.php:45 | Where bad value passed |
| Root Investigation | CreateOrderUseCase.php:45 | Start here |
Pattern: Null from Repository
#0 Repository->find() returns null
#1 Service uses result without check
#2 Controller calls service
→ Fix in #1: Add null check
Pattern: Type Coercion
#0 Method expects int, gets string
#1 Request data not validated
#2 Controller passes raw input
→ Fix in #1 or #2: Add validation/casting
Pattern: Missing Dependency
#0 Service->method() called
#1 Container->get() fails
#2 Dependency not registered
→ Fix: Register dependency in container
Trace data flow through the application.
// Trace the flow of $orderId
1. Controller receives $orderId from Request
2. UseCase receives $orderId as Command property
3. Repository uses $orderId in SQL query
4. Database returns null (ID doesn't exist)
5. UseCase passes null to Service
6. Service throws NullPointerException
# Find all callers of a method
grep -r "->calculateTotal(" src/
# Find all places where variable is set
grep -r "\$items\s*=" src/
# Find all null assignments
grep -r "= null" src/Domain/
Rebuild the sequence of state changes.
## State Timeline
T0: Initial state
- Order::status = DRAFT
- Order::items = []
T1: AddItemToOrder executed
- Order::items = [Item(id=1)]
- Expected: status stays DRAFT ✓
T2: SubmitOrder executed
- Order::status = SUBMITTED
- Expected: items preserved ✓
T3: PaymentReceived event
- Order::status = PAID
- BUG: items cleared unexpectedly ✗
T4: GetOrder query
- Returns Order with empty items
- User sees $0 total
Root Cause: PaymentReceived handler incorrectly reinitializes Order
| Bug Type | First Investigation Point |
|---|---|
| Null pointer | Repository/Factory that creates the null |
| Wrong calculation | Input values, not calculation logic |
| Missing data | Event handler or background job |
| Intermittent failure | Shared state or race condition |
| After deployment | Git diff between versions |
| Only in production | Environment config or data |
| Only for some users | User-specific data or permissions |
Provides UI/UX resources: 50+ styles, color palettes, font pairings, guidelines, charts for web/mobile across React, Next.js, Vue, Svelte, Tailwind, React Native, Flutter. Aids planning, building, reviewing interfaces.