Loading...
Loading...
Root cause analysis methods for PHP bugs. Provides 5 Whys technique, fault tree analysis, git bisect guidance, and stack trace parsing.
npx skill4agent add dykyi-roman/awesome-claude-code bug-root-cause-finderError 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 ACKOrder::getTotal()OrderItem## 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][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")# 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=OrderTotalTestFatal 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 |
#0 Repository->find() returns null
#1 Service uses result without check
#2 Controller calls service#0 Method expects int, gets string
#1 Request data not validated
#2 Controller passes raw input#0 Service->method() called
#1 Container->get() fails
#2 Dependency not registered// 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/## 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 |