Skip to content

Common Node.js Mistakes

This lesson goes deeper into the mistakes most frequently made by developers learning Node.js, why each one happens, and the specific fix, pulling together the most important pitfalls from across this entire course.

Why These Mistakes Are So Common

Many Node.js mistakes share a root cause: JavaScript's async model looks deceptively similar to synchronous code, so it's easy to assume ordering, error propagation, or blocking behavior that doesn't actually match what's happening underneath.

The rest tend to come from treating Node.js like a typical single-request-per-process language (missing connection pooling, missing rate limiting) rather than understanding its long-running, shared-process model.

// A classic combination of two common mistakes
app.get('/report', (req, res) => {
  const data = fs.readFileSync('./huge-report.csv', 'utf8'); // blocks everyone
  const rows = data.split('\n').map((line) => line.split(',')); // no error handling
  res.json(rows);
});

This single route blocks the entire server on every request and has no error handling at all if the file is missing or malformed, exactly the combination that causes production incidents.

The Most Frequent Categories

1. Blocking the event loop
2. Missing error handling (sync or async)
3. Callback/promise anti-patterns
4. Unsafe database queries
5. Missing input validation
6. Ignoring security headers/rate limiting
  • Blocking mistakes usually come from *Sync methods or heavy loops inside request handlers.
  • Missing error handling often stems from forgetting try/catch around await, or an 'error' listener on an emitter.
  • Unsafe queries almost always trace back to string concatenation instead of parameterized queries.

Common Mistakes Cheatsheet

The mistakes worth double-checking for in almost any Node.js codebase.

Mistake Why It's a Problem Fix
fs.readFileSync() in a route Blocks every other request Use async fs.promises methods
No try/catch around await Unhandled rejection can crash the process Wrap in try/catch, forward to error handler
String-built SQL queries SQL injection risk Use parameterized queries
No 'error' listener on an emitter Emitting 'error' with no listener crashes the process Always attach an error handler
Sequential awaits for independent calls Slower than necessary Use Promise.all()
Missing rate limiting on /login Vulnerable to brute-force attacks Add a strict rate limiter

Forgetting the 'error' Event

This specific mistake deserves extra attention because of how silently it fails until it doesn't: an EventEmitter (a stream, a server, a socket) that emits 'error' with no listener attached will crash the entire Node.js process, not just log a warning.

// Missing error handling: an unhandled 'error' event crashes the process
const stream = fs.createReadStream('./maybe-missing-file.txt');
stream.pipe(res);

// Fixed: always attach an error listener
stream.on('error', (err) => {
  res.status(404).json({ error: 'File not found' });
});
stream.pipe(res);

The N+1 Query Mistake

Looping over a list of results and issuing one additional database query per item, instead of a single batched query, is one of the most common performance mistakes in real applications, and often the easiest to fix once identified through profiling or slow query logs.

Common Mistakes

  • Assuming an async operation completed successfully without checking for an error.
  • Copying an old tutorial's code without checking whether it matches current best practices.
  • Not testing error paths (missing files, failed database calls, invalid input) at all.
  • Fixing the symptom of a mistake without understanding its root cause, only for it to reappear elsewhere.

Key Takeaways

  • Most common Node.js mistakes trace back to misunderstanding the async or event-driven model.
  • Blocking code, missing error handling, and unsafe queries are the highest-impact mistakes to catch early.
  • The unhandled 'error' event mistake is uniquely dangerous because it can crash the entire process.
  • N+1 query patterns are a frequent, fixable source of poor API performance.

Pro Tip

When reviewing someone else's Node.js code (or your own from months ago), specifically search for Sync(, .on('error' (or its absence), and raw string-built queries. These three searches alone catch a surprisingly large share of the mistakes covered in this lesson.