Bug

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.


1

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
2

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
  }
}
3

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 i
4

Loose 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 */ }
5

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

Undefined ErrorsAsync/Await MistakesClosure BugsEquality Operator BugsJavaScript Code Review Guide

Published by LearnCodeGuide Team · Last reviewed: October 2025