Something broke. Find out why.
Step into a failing system, follow the evidence, make the smallest safe change, and prove you fixed the right thing.
Your first green build starts here.
Reproduce a pagination failure, trace the off-by-one error, patch it, and verify the fix with a step-by-step coach.
Start with a guided labDebug the whole codebase.
Reproduce a failure, inspect unfamiliar code, make the smallest fix, and prove it survives visible and hidden checks.
Practice library
Choose your next failure.
Search by symptom, then pick the failure that feels worth chasing. Every lab starts broken and ends with proof that your fix works.
The Phantom Env Var
Works locally. Fails in CI after a config change.
Wrong Port, Right Service
Health check passes, traffic hits the admin service instead of the public API.
The Stale Lock
Deploy pipeline stuck because an old lock never expired.
AccessDenied at 3AM
Production job fails only after rotating credentials.
The Silent Timeout
Requests hang for 30 seconds, then succeed on retry.
Cache Stampede
Every morning at 9AM service slows to a crawl for 90 seconds.
The N+1 That Wasn't
DB load explodes, but the query count looks normal.
The Missing Header
API works in browser, fails in worker/client.
The Flaky Retry
Retry logic makes the outage worse.
The Broken Health Check
Deployment rolls back even though app is alive.
The Timezone Trap
Report fails only around midnight UTC.
The Case-Sensitive Config
Works on macOS, fails in Linux CI.
Pagination off by one
Page 1 skips the first N items.
CORS origin parsing bug
Regex origin validation allows malicious domains.
Cache key missing tenant id
Multi-tenant cache key uses just user_id, causing cross-tenant leaks.
The stale confirmation
A successful update is followed by an old value.
The missing trace ID
A downstream request loses its correlation header.
Half an import
A rejected batch still leaves earlier rows committed.
The log that ate the request
A debug log serializes an entire upload payload.
The Price That Refused to Update
Merchants change a price. Half the storefront still shows yesterday's number.
The Permission That Outlived the User
Security revokes a contractor. API logs still show successful deletes.
The Invoice That Forgot Quantity
Carts with quantity > 1 undercharge. Finance finds missing line totals.
The File That Left the Vault
A document download endpoint serves more than the vault folder.
The Dashboard That Averaged Averages
On-call swears p95 is fine. Customers still time out.
The Retry That Amplified Outages
When auth fails, clients hammer it harder. Traffic multiplies the outage.
The Header That Vanished Mid-Flight
Authenticated upstream calls 401 even though the client set Authorization.
The Query That Loaded the World
Orders list endpoint returns every tenant's rows and times out under load.
The Event That Fired Twice
Webhook side effects run twice after every reconnect.
The Config That Swallowed Prod
Production boots with the dev database URL and debug flags.
The Filter That Swallowed False
?includeDeleted=false still returns soft-deleted rows.
The Token That Never Expired
Revoked sessions still authorize long after their expiresAt.
The Redirect That Left the Building
Login next= parameter sends users to attacker-controlled hosts.
The Rate Limit That Counted Everyone
One noisy tenant trips the rate limit for every customer on the node.
The Lock That Never Let Go
After one failing job, every later attempt waits forever on the same lock.
The Webhook That Trusted Silence
Unsigned webhook deliveries are accepted when the signature header is missing.
Duplicate webhook processing
Each request registers another event listener, so later webhooks are processed multiple times.
HTTP method casing mishandled for non-standard verbs
A Request constructor accepts a method option. The library normalizes the six standard HTTP methods (DELETE, GET, HEAD, OPTIONS, POST, PUT) to uppercase regardless of input casing, while preserving every other method string exactly as supplied. Currently, the casing rule applies too broadly, altering method names that should pass through untouched.
Repeated trailing slashes in base URL
When a base URL like 'https://api.github.com///' is joined with a path like '/users', the resulting URL contains an extra slash between the host and the path instead of a single separator.
Zero-value entries-read argument omitted from XGROUP tokens
A caller passes the ENTRIESREAD option set to 0 to XGROUP CREATE or XGROUP SETID. The argument builder should emit the ENTRIESREAD keyword and a '0' token. Instead, when the option value is exactly 0, the trailing ENTRIESREAD and '0' tokens are missing from the produced array.
App.render rejects null and undefined options values
A caller invokes `app.render(viewName, options, callback)` and expects the callback to deliver the rendered template string even when `options` is `null` or `undefined`. The callback does not deliver the expected rendered output for those cases, while rendering with a normal options object continues to succeed.
Idempotency key ignored
The payment endpoint validates an idempotency key but drops it before the database call.