Common JavaScript Bugs — Real Examples and Fixes
JavaScript's loose typing and async model create a unique set of bugs that trip up developers at every level. These are the most common JavaScript errors in production code — with working examples you can test right now.
What is a JavaScript bug?
JavaScript bugs range from silent type coercion producing wrong results to unhandled promise rejections crashing Node.js servers. Because JavaScript runs in browsers and servers, a single bug can affect millions of users simultaneously.
undefined is not a function
Calling a method on undefined or null is the #1 JavaScript runtime error. Happens when an API response has unexpected shape.
❌ Crashes on null data
const user = await getUser(id); const email = user.profile.email.toLowerCase(); // TypeError: Cannot read properties of null at email.toLowerCase // Happens when: user=null, user.profile=undefined, email=null
✅ Optional chaining + nullish coalescing
const user = await getUser(id); const email = user?.profile?.email?.toLowerCase() ?? 'no-email'; // ?. short-circuits if any part is null/undefined // ?? provides a default value if the result is null/undefined
Async/Await Without Error Handling
Unhandled rejected Promises cause silent failures in browsers and crash Node.js servers in older versions.
❌ Unhandled rejection
async function loadData() {
const data = await fetch('/api/data').then(r => r.json());
return data; // If fetch fails, error propagates silently
}
// Also: forgetting await
const user = getUser(id); // Returns Promise, not user!
console.log(user.name); // undefined — Promise has no .name✅ Proper async error handling
async function loadData() {
try {
const response = await fetch('/api/data');
if (!response.ok) throw new Error(`HTTP ${response.status}`);
return await response.json();
} catch (error) {
console.error('Failed to load data:', error);
return null; // Return safe default
}
}var Hoisting and Closure Loops
Variables declared with var are hoisted to function scope and shared across loop iterations, causing classic closure bugs.
❌ All callbacks print 5
for (var i = 0; i < 5; i++) {
setTimeout(() => console.log(i), 100); // Prints: 5 5 5 5 5
}
// var i is shared — all callbacks see the final value✅ let creates new binding per iteration
for (let i = 0; i < 5; i++) {
setTimeout(() => console.log(i), 100); // Prints: 0 1 2 3 4
}
// let has block scope — each iteration has its own iLoose Equality (== instead of ===)
JavaScript's == performs type coercion, producing counterintuitive results that cause bugs in conditionals.
❌ Type coercion surprises
console.log(0 == false) // true — number vs boolean
console.log("" == false) // true — string vs boolean
console.log(null == undefined) // true — special case
console.log("0" == false) // true — all evaluate as falsy
if (user.role == 0) { /* triggers for role=false, role="" too */ }✅ Always use === for comparison
console.log(0 === false) // false — different types
console.log("" === false) // false — different types
if (user.role === 0) { /* only triggers for exact number 0 */ }
// Check for null/undefined explicitly:
if (value == null) { /* intentional: catches both null and undefined */ }this Context Lost in Callbacks
Arrow functions inherit this from surrounding scope. Regular function callbacks lose this, causing undefined property access.
❌ this is undefined in callback
class Timer {
constructor() { this.count = 0; }
start() {
setInterval(function() {
this.count++; // TypeError: this is undefined
}, 1000);
}
}✅ Arrow function preserves this
class Timer {
constructor() { this.count = 0; }
start() {
setInterval(() => {
this.count++; // Works — arrow function inherits outer this
}, 1000);
// Alternative: const self = this; ... self.count++
}
}Pro tip: Enable ESLint with no-undef, eqeqeq, and no-var rules. Better yet, migrate to TypeScript strict mode — it catches most of these at compile time.
Detect JavaScript Bugs Automatically
Paste your code — LearnCodeGuide detects all these issues automatically using GPT-4o + Claude Sonnet. Free to start.
Analyze JavaScript Code →Related Guides
Published by LearnCodeGuide Team · Last reviewed: October 2025