Skip to main content
JG is here with you ✨
Back to Blog
EXPLAIN3WAY

Debug Like a Pro: The Art of Finding What's Broken

Every developer encounters bugs. The difference between frustration and flow is knowing how to find them. Here's the systematic approach that turns mystery errors into quick fixes.

12 min2025-12-01

Debug Like a Pro: The Art of Finding What's Broken

Here's a truth nobody tells beginners: professional developers spend a huge chunk of their time debugging.

Not because they're bad at coding—because bugs are inevitable. The difference between a frustrated beginner and a calm professional isn't the number of bugs they encounter. It's how quickly they find and fix them.

This article teaches you the detective mindset. How to read error messages (they're actually helpful once you know how). How to isolate problems. How to clear the caches that cause phantom bugs. By the end, you'll approach errors with curiosity instead of dread.

No advanced skills required. If you've ever wondered "why isn't this working?", this is for you.

Explain it three ways

👶 Like I'm 5

When your toy stops working, you don't throw it away—you check if the batteries are in right, if something's stuck, or if it needs new batteries. Debugging is the same: checking things one by one until you find what's wrong. It's like being a detective for broken toys!

💼 Like you're my boss

Debugging skills directly impact velocity. A developer who can systematically diagnose issues spends hours less per bug than one who guesses randomly. This training reduces mean time to resolution across the team. ROI: faster incident response, less developer frustration, more predictable timelines.

💕 Like you're my girlfriend

You know when I get frustrated staring at code? This is about learning to be a detective instead of getting stressed. Read the clues, check things systematically, and the answer usually reveals itself. It's like when we troubleshoot why the WiFi isn't working—check the obvious stuff first, then dig deeper.

The debugging mindset

Before we get into techniques, let's talk about attitude.

Bugs are not personal attacks. They're puzzles. The code isn't trying to frustrate you—it's doing exactly what you told it to do. The bug is the gap between what you intended and what you actually wrote.

Frustration clouds judgment. When you feel yourself getting angry, take a 5-minute break. Walk around. Get water. Come back with fresh eyes. I've solved more bugs in the first minute after a break than in the previous hour of frustrated staring.

The error message is your friend. It's literally telling you what's wrong. Most developers panic and Google immediately. Try reading the actual message first—it often contains the answer.

Reading error messages (they're trying to help)

Error messages follow a pattern:

TypeError: Cannot read properties of undefined (reading 'name')
    at UserCard (src/components/UserCard.tsx:12:15)
    at renderWithHooks (react-dom.development.js:14985:18)

Line 1: What broke

Cannot read properties of undefined (reading 'name') = You tried to access .name on something that doesn't exist.

Line 2: Where to look

at UserCard (src/components/UserCard.tsx:12:15) = The problem is in UserCard.tsx, line 12, character 15.

The rest: The trail

This is the "stack trace"—the path the code took to get here. Look for YOUR files (not react-dom or node_modules).

💡 The translation trick

When you see an error, translate it to plain English. "Cannot read properties of undefined" becomes "I tried to use something that doesn't exist." Now you know what to look for: where is that thing supposed to come from, and why is it missing?

The debug checklist

When something breaks, work through this list in order:

StepActionWhat you're looking for
--------------------------------------
1Read the full error messageWhat exactly does it say? What file and line?
2Check the browser consoleAny red errors or yellow warnings?
3Check the terminalIs the dev server showing errors?
4Add console.log before the errorWhat are the actual values at that point?
5Google the exact error messageHas someone else solved this?
6Clear caches and restartCould this be stale code?
7Simplify and isolateCan I reproduce this with less code?
8Ask for help with contextInclude error, code, and what you tried

Most bugs are solved by steps 1-4. Seriously. Read the error, check the console, log some values.

Strategic console logging

console.log is powerful when used strategically. Random logs create noise. Strategic logs reveal truth.

Always label your logs

// Bad - you'll forget which is which
console.log(data);
console.log(user);

// Good - clear labels
console.log("API response:", data);
console.log("Current user:", user);

Use console.table for arrays and objects

const users = [
  { name: "Alex", age: 28 },
  { name: "Sam", age: 32 }
];

console.table(users);  // Shows a nice table in the console

Use console.group for related logs

console.group("User Authentication");
console.log("Token:", token);
console.log("User ID:", userId);
console.log("Permissions:", permissions);
console.groupEnd();

Clean up when done

Leave console.log statements in production code and you'll eventually log sensitive data. Remove them before committing, or use a debug flag:

const DEBUG = process.env.NODE_ENV === 'development';

if (DEBUG) {
  console.log("Debug info:", data);
}

The four common React bugs

1. "Cannot read properties of undefined"

The bug:

function UserCard({ user }) {
  return <h1>{user.name}</h1>;  // Crashes if user is undefined
}

// Called without props:
<UserCard />

The fix:

function UserCard({ user }) {
  if (!user) return <p>No user data</p>;
  return <h1>{user.name}</h1>;
}

// Or with optional chaining:
<h1>{user?.name ?? "Unknown"}</h1>

2. "Each child in a list should have a unique key"

The bug:

{todos.map(todo => (
  <li>{todo.text}</li>  // Missing key
))}

The fix:

{todos.map(todo => (
  <li key={todo.id}>{todo.text}</li>  // Use unique ID from data
))}

⚠️ Don't use array index as key

key={'{'}index{'}'} seems to work but causes bugs when you add, remove, or reorder items. Always use a unique ID from your data. If your data doesn't have IDs, add them.

3. "Too many re-renders"

The bug:

function Counter() {
  const [count, setCount] = useState(0);
  setCount(count + 1);  // Called during render = infinite loop
  return <p>{count}</p>;
}

The fix:

function Counter() {
  const [count, setCount] = useState(0);
  
  const increment = () => setCount(count + 1);  // Called on click, not during render
  
  return (
    <button onClick={increment}>{count}</button>
  );
}

4. Stale state in event handlers

The bug:

const handleClick = () => {
  setCount(count + 1);
  setCount(count + 1);  // Both use the same stale 'count' value
  // Expected: +2, Actual: +1
};

The fix:

const handleClick = () => {
  setCount(prev => prev + 1);
  setCount(prev => prev + 1);  // Each uses the latest value
  // Now correctly adds 2
};

The cache clear dance

When code should work but doesn't, stale caches are often the culprit.

What to clearCommand/ActionWhat it fixes
----------------------------------------------
Browser cacheCtrl+Shift+R (Win) / Cmd+Shift+R (Mac)Old JS/CSS still loading
Next.js cacheDelete `.next` folder, restart devBuild artifacts from old code
Node modulesDelete `node_modules`, run `npm install`Corrupted or outdated packages
npm cache`npm cache clean --force`Global npm issues
Vercel cacheRedeploy with "Clear Cache"Production showing old version

The nuclear option: When nothing else works:

rm -rf .next node_modules
npm install
npm run dev

This takes a minute but solves most "it works on my machine" mysteries.

The isolation technique

When you can't find the bug, make the problem smaller.

Step 1: Comment out half the code

Does it still break? The bug is in the remaining half. Doesn't break? The bug is in what you commented out.

Step 2: Repeat

Keep halving until you find the exact line.

Step 3: Create a minimal reproduction

Can you reproduce the bug with just 10 lines of code? This often reveals the issue—and if you need to ask for help, a minimal example gets faster answers.

✨ The rubber duck method

Explain the problem out loud, step by step, as if teaching someone who knows nothing. A rubber duck works. A pet works. An empty chair works. The act of explaining often reveals the answer mid-sentence. It sounds silly. It works.

Quick reference: Bug symptoms and causes

SymptomLikely cause
-----------------------
Blank page, no errorsUncaught async error, missing return, broken import
Styles not applyingClass name typo, Tailwind purging, CSS specificity
State not updatingMutating state directly, missing dependency array
Infinite loopsetState in render, missing useEffect deps
"X is not defined"Import missing, typo in variable name
"X is not a function"Wrong import, undefined value
Works locally, breaks in productionEnvironment variables, build-time vs runtime

Your practice challenge

Debug this component (there are 3 bugs):

function TodoList({ todos }) {
  const [filter, setFilter] = useState("all");
  
  setFilter("active");  // Bug 1
  
  return (
    <ul>
      {todos.map(todo => (
        <li>{todo.text}</li>  // Bug 2
      ))}
      <button onClick={setFilter("completed")}>  // Bug 3
        Show Completed
      </button>
    </ul>
  );
}

Find all three bugs and explain why each one causes problems.

What's next?

Debugging is a skill that improves with practice. Every bug you solve adds to your pattern recognition. Eventually, you'll see an error and immediately know where to look.

Interactive lab available

Want to practice debugging hands-on? The companion lab lets you:

  • Diagnose real bug scenarios step by step
  • Practice reading error messages
  • Learn the cache clear dance
  • Track your bug-squashing progress

<a href="/learn-ai-lab/skill-boosters/debug-like-pro" className="text-rose-300 hover:text-rose-100 underline">→ Try the Debug Like a Pro Lab</a>

Open to AI-Focused Roles

AI Sales • AI Strategy • AI Success • Creative Tech • Toronto / Remote

Let's connect →
Terms of ServiceLicense AgreementPrivacy Policy
Copyright © 2026 JMFG. All rights reserved.