FullStack Course LogoFullStack Course

Debugging Playbook

Debugging Playbook Debugging is a repeatable investigation, not random editing. Start with the setup and deployment guide for environment problems and use the testing strategy to turn a fix into evidence. Five-step loop

Debugging is a repeatable investigation, not random editing. Start with the setup and deployment guide for environment problems and use the testing strategy to turn a fix into evidence.

Five-step loop

  1. Reproduce the problem with the smallest reliable input.
  2. Read the first useful error and record its file, line, type, and message.
  3. State the expected result and the observed result.
  4. Inspect evidence at the failing boundary.
  5. Change one thing, retest, and explain why the change should work.

Before changing code

  • Capture the exact command, URL, input, browser/runtime version, and environment.
  • Check whether the failure is local-only, data-specific, timing-dependent, or reproducible after a clean restart.
  • Read the first relevant error, not every downstream symptom. Keep a small reproduction and a known-good comparison.
  • Confirm which boundary fails: source/build, browser, network, server, database, or deployment.

Browser failures

  • Blank page: inspect Console and confirm the script path.
  • Missing style: inspect Network and verify the stylesheet URL and response type.
  • Click does nothing: verify the selector, event listener, and handler error.
  • Wrong value: log inputs and intermediate values, then inspect types.
  • Fetch failure: inspect URL, method, status, response body, CORS, and cancellation state.
  • Build failure: run the failing script directly, check the working directory and Node version, then inspect the first TypeScript/lint error before changing configuration.
  • Routing after deployment: confirm the asset base path, case-sensitive filenames, SPA fallback, and that the deployed build contains the requested file.

React failures

Ask which state produced the screen, which component owns it, and whether a value is derived or duplicated. Do not fix a stale value by adding an effect until the data flow is understood. Check the component boundary, props, key stability, loading/error branches, effect cleanup, and network cache before changing state architecture.

Server failures

Check the request method, path, headers, parsed body, route order, validation result, database query, status code, and server logs. Reproduce the request with a known payload before changing the frontend.

Database failures

Separate connection failure, query failure, validation failure, cast failure, missing document, and authorization failure. They require different fixes and should not all become a generic frontend error.

Deployment failures

  1. Verify the build locally with npm run verify:release from reader/.
  2. Confirm the deployed commit, build command, output directory, Node version, and required environment variables.
  3. Open the deployed app in a private window and inspect Console, Network, response headers, and the server/platform logs.
  4. Test the health endpoint and one representative user flow without exposing secrets or real user data.
  5. If rollback is available, compare the last known-good deployment before making another change.

Never debug by printing credentials, session cookies, full authorization headers, or personal data. Redact incident notes and rotate a secret if it was exposed.

Incident debugging

Treat an incident as a time-bounded investigation:

  1. Assign an owner and write the customer-visible symptom, start time, scope, and severity.
  2. Compare the first failing request with a known-good request. Preserve request ID, release/commit, status, duration, sanitized route, and dependency health.
  3. Use logs for event detail, metrics for rate/latency/resource trends, and traces for cross-service timing. Follow one request ID from browser Network tools through API logs and database timing.
  4. Check recent deploys, configuration, traffic, dependency, and schema/index changes. Do not assume the newest deploy is the cause.
  5. Mitigate first when safe: disable a flag, stop a consumer, reduce traffic, or roll back the immutable artifact. Then reproduce and fix the root cause.
  6. Verify recovery with health/readiness, the affected journey, graphs, and a regression test. Record follow-up owners and deadlines.

Worked example: task creation returns 201 but the list is empty. The browser request ID is r-42; the API log shows 201, while the following GET queries a different database host after deployment. Readiness was green because it checked process liveness only. Roll back, then add startup configuration validation and a smoke test that creates and reads a disposable task.

Evidence checklist

  • Exact reproduction and expected/observed behavior are written down.
  • Boundary and first failing input are named.
  • Release, environment, request ID, status, duration, and dependency health are captured.
  • Sensitive values are redacted; logs contain no credentials, cookies, tokens, hashes, or full personal payloads.
  • One change is tested with a regression test and a clean rerun.
  • Mitigation, rollback decision, recovery evidence, and prevention owner are recorded.

Professional habit

Write a short incident note for difficult bugs: symptom, cause, evidence, fix, regression test, and prevention. This turns a frustrating failure into reusable engineering knowledge.

Reader page: /guide/debugging-playbook