Common Bug Patterns
Recognize the most common bug patterns — off-by-one errors, null references, race conditions, async issues, and type mismatches — to identify bugs faster.
🔄 Recall Bridge: In the previous lesson, you learned debugging tools — print statements, IDE debuggers, and browser DevTools. Now let’s build your pattern recognition: the common bug types that cause 80% of all bugs.
Experienced developers debug faster because they’ve seen the same bug patterns hundreds of times. When they see “index out of bounds,” they immediately check loop boundaries (off-by-one). When results are intermittent, they look for race conditions. Pattern recognition turns 30-minute investigations into 30-second diagnoses.
The Top Bug Patterns
Pattern 1: Off-by-One Errors
Symptoms: Array index out of bounds, missing first/last element, extra iteration
| Variant | Wrong | Correct |
|---|---|---|
| Loop boundary | i <= array.length | i < array.length |
| Start index | for i in range(1, n) | for i in range(0, n) |
| Slice end | str.slice(0, str.length - 1) | Depends on intent |
| Pagination | page 1 = items 1-10 | page 1 = items 0-9 (or 1-10?) |
Pattern 2: Null/Undefined References
Symptoms: “Cannot read property of null/undefined,” NullPointerException
Common causes:
| Cause | Example | Prevention |
|---|---|---|
| API returns null | user.profile.avatar when profile is null | Optional chaining: user?.profile?.avatar |
| Missing function parameter | function greet(name) { name.toUpperCase() } called without args | Default parameters or null checks |
| Uninitialized variable | Using result before async call finishes | Initialize with default value |
| Wrong property name | data.username when the field is data.user_name | Check actual API response shape |
Pattern 3: Race Conditions
Symptoms: Works sometimes, fails intermittently, logging makes it “disappear”
AI prompt for race condition diagnosis:
My code calls [OPERATION A] and [OPERATION B] and uses both results. It works 90% of the time but sometimes produces wrong results. Here’s my code: [PASTE]. Is there a race condition? If so, how do I fix it to ensure correct results regardless of execution order?
Pattern 4: Async/Await Errors
Symptoms: Function returns Promise instead of value, undefined result from API call
| Error | Cause | Fix |
|---|---|---|
Returns [object Promise] | Missing await | Add await before async call |
| Undefined result | Callback-based function in async code | Wrap in new Promise() or use promisify |
| Unhandled rejection | Missing .catch() or try/catch | Wrap async code in try/catch |
| Sequential instead of parallel | Awaiting in a loop | Use Promise.all() for independent calls |
Pattern 5: Type Mismatches
Symptoms: “1” + 1 = “11” instead of 2, wrong comparison results
| Issue | Cause | Fix |
|---|---|---|
| String concatenation | "5" + 3 === "53" | Number("5") + 3 or parseInt("5") + 3 |
| Loose equality | "0" == false is true | Use === for strict equality |
| JSON parsing | API returns string, expected object | JSON.parse(response) if needed |
| Boolean coercion | if ("false") is true | Compare explicitly: if (value === "true") |
Pattern 6: State Mutation Bugs
Symptoms: Value changed “mysteriously,” function has side effects
Common cause: Modifying a shared object/array instead of creating a copy.
✅ Quick Check: Your search function returns results for the previous query, not the current one. The user types “hello,” results show for “hell.” What pattern is this? (Answer: A stale closure or debounce timing issue. The search handler captures the old query value. Either: (1) The debounce fires with the old value (fix: use the latest value, not the captured one), or (2) An older API response arrives after a newer one (fix: cancel or ignore stale responses using an abort controller or request ID).)
AI for Pattern Recognition
AI prompt when you’re stuck:
I have a bug with these symptoms: [DESCRIBE]. Which of these common bug patterns does this match: off-by-one, null reference, race condition, async error, type mismatch, state mutation, stale closure, or something else? For the matched pattern, suggest the most likely cause and fix.
Key Takeaways
- Off-by-one errors and null references are the two most common bug patterns — when you see “index out of bounds” check loop boundaries, when you see “cannot read property of null” trace backward to find where the null value originated
- Race conditions are identifiable by their symptoms: works in development but fails intermittently in production, and adding logging makes the problem disappear (because logging changes execution timing) — fix by never assuming async operations complete in a specific order
- Build a mental library of bug patterns: when you encounter a bug, match its symptoms to known patterns first — experienced developers debug 40-60% faster because they recognize patterns instead of investigating from scratch every time
Up Next
In the next lesson, you’ll learn to debug production issues — where you can’t attach a debugger, can’t add print statements, and must investigate through logs, monitoring, and error tracking.
Knowledge Check
Complete the quiz above first
Lesson completed!