Use when the user shares a Sentry error, Jira bug ticket, or error description and wants root cause analysis. Also for proactive bug hunting and code audits for hidden bugs.
Scanned 6/5/2026
Install via CLI
openskills install event4u-app/agent-config---
model_tier: high
name: bug-analyzer
description: "Use when the user shares a Sentry error, Jira bug ticket, or error description and wants root cause analysis. Also for proactive bug hunting and code audits for hidden bugs."
domain: discovery
council_depth: deep
workspaces:
- engineering
packs:
- engineering-base
---
# bug-analyzer
## When to use
**Reactive mode:** User reports a bug, shares a Sentry issue, or asks to investigate an error.
**Proactive mode:** User asks to audit code for hidden bugs, edge cases, or risky patterns.
Do NOT use when:
* Feature development — route to [`feature-planning`](../feature-planning/SKILL.md)
* Code style or refactoring — route to [`code-refactoring`](../code-refactoring/SKILL.md)
* Performance issues — route to [`performance-analysis`](../performance-analysis/SKILL.md)
* Security vulnerabilities — route to [`security-audit`](../security-audit/SKILL.md)
* You need to trace how one data element flows through the code — route to
[`data-flow-mapper`](../data-flow-mapper/SKILL.md)
* You need to enumerate every call site / consumer affected by a planned fix —
route to [`blast-radius-analyzer`](../blast-radius-analyzer/SKILL.md)
## Input sources
Bugs can come from multiple sources — gather as many as available:
| Source | What it provides |
|---|---|
| **Branch name** | Auto-detected ticket ID (e.g., `fix/DEV-1234/...`) |
| **Jira ticket** | Description, acceptance criteria, comments, priority |
| **Sentry issue URL** | Stacktrace, affected users/environments, frequency, tags |
| **Sentry event ID** | Specific occurrence with full context |
| **Error message** | String to search in codebase |
| **User description** | Reproduction steps, expected vs. actual behavior |
### Branch ticket detection
Always check the current branch for ticket IDs:
```
git branch --show-current
```
Pattern matching:
- `fix/DEV-1234/description` → extract `DEV-1234`
- `fix/PROJ-567-some-bug` → extract `PROJ-567`
- `hotfix/DEV-999` → extract `DEV-999`
- Regex: `[A-Z]+-[0-9]+`
If found, auto-fetch the ticket and confirm with the user.
## The Iron Law
```
NO FIXES WITHOUT ROOT CAUSE INVESTIGATION FIRST
```
If you haven't completed Phase 1, you cannot propose fixes. Random fixes waste time and
create new bugs. Quick patches mask underlying issues.
### Red flags — STOP immediately
- "Quick fix for now, investigate later"
- "Just try changing X and see if it works"
- "It's probably X, let me fix that"
- Proposing solutions before tracing data flow
- "One more fix attempt" (when already tried 2+)
## Procedure: Analyze a bug
1. **Inspect inputs and reproducers** — Pull every source named in *Input sources* (branch, Jira, Sentry, error string, user description) before forming a hypothesis.
2. **Investigate root cause** — Run Phase 1 below; gather evidence, walk the stacktrace, consult engineering memory.
3. **Find the pattern** — Run Phase 2; check for similar bugs elsewhere in the codebase.
4. **Form and test a hypothesis** — Run Phase 3; write a failing test that reproduces the bug.
5. **Fix and verify** — Run Phase 4; apply the minimal change, re-run the failing test plus the wider suite.
### Phase 1: Root Cause Investigation
Gather all available evidence before forming any hypothesis:
- **Sentry URL** → use `get_issue_details` to fetch stacktrace, tags, environments, frequency.
- **Sentry issue** → use `get_issue_tag_values` for browser, URL, environment distribution.
- **Jira ticket** → fetch via Jira API, read description, comments, linked issues.
- **Error message** → search the codebase for the message string.
- **Branch name** → auto-detect ticket ID, fetch if found.
- **Stacktrace** → start from top frame (crash site), trace down to entry point.
- Use `codebase-retrieval` to find the relevant code.
- Read each file in the call chain to understand the data flow.
- Check existing context docs (`agents/settings/contexts/`) for the affected area.
- **Consult engineering memory.** Via
[`memory-access`](../../../docs/guidelines/agent-infra/memory-access.md) call
`retrieve(types=["historical-patterns", "incident-learnings"],
keys=[<error class>, <affected file paths>], limit=3)`. A prior
matching pattern or incident is the single most reliable accelerator
for root-cause analysis. Cite `id` and `path` verbatim so the user
can verify the precedent.
#### Multi-component diagnostics
When the system has multiple layers (Controller → Service → Repository → DB, or multi-tenant
DB switching), add diagnostic instrumentation **before** proposing fixes:
```
For EACH component boundary:
- Log what data enters the component
- Log what data exits the component
- Verify environment/config propagation (e.g. DB connection, tenant context)
- Check state at each layer
Run once → gather evidence → identify WHICH layer breaks → investigate that layer.
```
This is especially important for:
- Multi-tenant database switching (wrong DB selected)
- Queue jobs that lose tenant context
- API → Service → Repository chains with data transformation
- External service integrations (ProBauS, GPS, etc.)
### Phase 2: Pattern Analysis
- Find **working examples** of similar code paths in the codebase.
- Compare the broken path against the working reference.
- Identify the **specific difference** that causes the failure.
- Check if the issue is isolated or part of a broader pattern.
### Phase 3: Hypothesis and Testing
- Form a **single hypothesis** based on evidence from Phase 1 and 2.
- Test the hypothesis minimally — don't change multiple things at once.
- If the hypothesis is wrong, go back to Phase 1 with new evidence.
- **3-Strikes Rule:** If 3+ fix attempts fail, STOP. This signals an architectural problem,
not a bug. Discuss with the user before attempting more fixes. Signs:
- Each fix reveals new shared state or coupling in a different place.
- Fixes require "massive refactoring" to implement.
- Each fix creates new symptoms elsewhere.
- Common root causes in this project:
- **Missing validation** on external sync data (CSV, XML, JSON imports).
- **Null values** from optional DB columns not handled.
- **Type mismatches** between legacy DB columns and PHP code.
- **Race conditions** in multi-tenant database switching.
- **Missing fallbacks** when external services are unavailable.
### Phase 4: Implementation
- Present the root cause and proposed fix **before implementing**.
- Create a **failing test** that reproduces the bug.
- Implement a **single, focused fix** — not multiple changes.
- Consider side effects — does the fix affect other code paths?
- Check if similar patterns exist elsewhere that need the same fix.
- Add validation/monitoring (e.g. `MonitoringHelper::captureException()`) for data quality issues.
- Verify the fix with the test from step 1.
## Proactive mode (bug hunting)
When asked to audit code for hidden bugs, use this workflow instead of the 4 phases above:
### 1. Execution tracing
Trace the actual code path step by step:
- Follow data through each function call
- Track state mutations and side effects
- Note where exceptions are caught or swallowed
- Identify where assumptions are made but not validated
### 2. Edge case analysis
For each code path, test these scenarios mentally:
| Category | What to check |
|---|---|
| **Null/empty** | Null inputs, empty arrays, empty strings, missing keys |
| **Boundaries** | Zero, negative, max int, first/last element |
| **Type coercion** | String "0" vs int 0, loose comparison bugs |
| **Timing** | Race conditions, stale cache, concurrent writes |
| **State** | Uninitialized state, partial updates, rollback failures |
| **External** | Network timeout, API errors, malformed responses |
### 3. Known bug patterns (PHP/Laravel)
- N+1 queries hidden in loops or accessors
- Missing `->fresh()` after update when using same instance
- Eloquent lazy loading in queued jobs (serialization issues)
- `now()` timezone mismatches
- Missing FK constraints allowing orphaned records
- `DB::transaction()` with external side effects (emails, API calls)
- Model events firing during seeding or migration
- Off-by-one errors in pagination or date ranges
- Silent exception swallowing (`catch (\Exception $e) {}`)
- Floating point comparison for money/quantities
### 4. Output format (proactive mode)
For each bug found: **Bug** → **Location** → **Severity** → **Root Cause** → **Trigger** → **Fix** → **Confidence**
## Commands
| Command | Purpose |
|---|---|
| `bug-investigate` | Gather context from all sources, analyze, identify root cause |
| `bug-fix` | Plan the fix, implement, verify with tests and quality tools |
## Project awareness
Read `AGENTS.md` and `./agents/` for project-specific architecture, business rules, and domain docs.
Detect the project from the repo name (see `rules/architecture.md`).
Check for existing contexts in `agents/settings/contexts/` or module `agents/settings/contexts/`.
## Adversarial review
Before implementing a fix, run the **`adversarial-review`** skill.
Focus on the "Bug fixes" attack questions: Is this the root cause or a symptom? Will the fix break something else?
## Auto-trigger keywords
- bug investigation
- error analysis
- Sentry error
- stacktrace
- root cause
## Rationalization prevention
| Excuse | Reality |
|---|---|
| "Should work now" | RUN the verification — confidence ≠ evidence |
| "It's probably X, let me fix that" | "Probably" = guessing. Complete Phase 1 first |
| "Quick fix for now" | Quick fixes mask root causes and create technical debt |
| "I'll investigate later" | Later never comes. Investigate now |
| "One more fix attempt" (after 2+) | 3+ failures = architectural problem. Stop and discuss |
| "Issue is simple, don't need process" | Simple issues have root causes too. Process is fast for simple bugs |
| "Emergency, no time for process" | Systematic debugging is FASTER than guess-and-check thrashing |
## Output format
1. Root cause analysis with evidence trail
2. Fix implementation or fix plan with specific files and changes
3. Regression test covering the failure scenario
## Verification examples
- **Backend bug**: reproduce with `curl` against the failing route (or an `actingAs()` HTTP test) before and after the fix; assert the new response shape with `assertJsonPath`.
- **Runtime bug**: place a `xdebug` breakpoint at the suspect frame, step through, and inspect the stack trace; for log-only repros, dump the failing variable with `dd(` once, then remove.
- **Regression test**: add a test that reproduces the original failure first (red), then makes it green — never write the test post-fix from memory.
## Gotcha
- Don't assume the stacktrace shows the root cause — it often shows the symptom. Trace backwards.
- Sentry groups similar errors — check if the "latest event" is actually representative of the issue.
- The model tends to suggest fixes without verifying the fix doesn't break other code paths.
## Do NOT
- Do NOT start fixing before understanding the root cause.
- Do NOT commit or push without permission.
- Do NOT ignore Sentry data if available — it provides real-world context.
- Do NOT fix only the symptom — trace to the root cause.
- Do NOT attempt fix #4 without discussing the architecture with the user.
## References
- **Chain-of-Verification (CoVe)** — [arxiv.org/abs/2309.11495](https://arxiv.org/abs/2309.11495)
Generate candidate answers, then verify each with follow-up
questions. This skill adapts CoVe by verifying stacktrace-derived
hypotheses against Sentry data and surrounding code before fixing.
No comments yet. Be the first to comment!