DM
All learning areas
Practice

Debugging Challenges

Reason through symptoms, evidence, root causes, fixes, and prevention.

Topic library

React infinite renderMissing effect cleanupAPI request race conditionSQL N+1 queryBroken authorization checkMemory leakUnhandled promise rejectionSlow database queryDuplicate webhook processingIncorrect cursor paginationStale cacheDocker networking failureWorks locally but fails in CI

Featured challenges

Read the symptom and code before revealing the investigation.

React infinite render

The page freezes and the console reports too many renders.

function Profile({ user }) {
  const [name, setName] = useState("");
  setName(user.name);
  return <input value={name} />;
}
Reveal investigation and fix ↓
  1. Symptom: rendering calls a state setter, which schedules another render.
  2. Root cause: synchronization is happening unconditionally in the component body.
  3. Fix: initialize from props, derive the value, or synchronize in a carefully scoped effect.
  4. Prevention: treat rendering as pure and avoid duplicated state.

Key idea: Do not update state during render.

Duplicate webhook processing

A customer receives the same fulfillment twice even though the provider sent a valid event.

await fulfillOrder(event.data.object);
return new Response("ok");
Reveal investigation and fix ↓
  1. Evidence: logs show the same provider event ID delivered more than once.
  2. Root cause: webhook delivery is at-least-once, but the consumer assumes exactly once.
  3. Fix: persist the provider event ID under a unique constraint before side effects.
  4. Prevention: make handlers idempotent and provide safe replay tooling.

Key idea: Retries are normal; duplicate side effects are a design bug.

Works locally, fails in CI

Tests pass on a laptop but fail intermittently in a clean Linux runner.

import config from "./Config";
// Actual file: ./config.ts
Reveal investigation and fix ↓
  1. Compare operating system, runtime version, environment variables, and lockfile usage.
  2. Run from a clean checkout with the same command and runtime as CI.
  3. Check case-sensitive paths, timezone assumptions, ordering, ports, and shared test state.
  4. Pin the environment and remove the hidden dependency.

Key idea: Reproduce the environment before changing the test.