DEV Community

Cover image for The One Line of Code That Crashes Most Node.js Apps
Arunangshu Das
Arunangshu Das

Posted on

The One Line of Code That Crashes Most Node.js Apps

“It was just one line.”
 
That’s what every developer says before their Node.js app crashes in production.
 
Whether it’s a sleepy Sunday morning deployment or a high-traffic Black Friday backend surge, this one seemingly harmless line of code sneaks in quietly… and blows things up spectacularly.

The Culprit: JSON.parse(req.body)

Yes, that’s it.

This seemingly innocent line is the silent killer of countless Node.js apps, especially in Express-based servers and APIs.

Let’s break it down and explain why it causes so much trouble.

1. What Happens When You Call JSON.parse(req.body) Directly?

Most developers know that when working with an incoming request in Express or Node’s built-in http module, the req.body contains the data sent by the client.

But here’s the kicker:

req.body is not always a string.

If you're using a body parser like express.json(), then req.body is already an object. Parsing it again with JSON.parse() leads to a crash.

Here’s what a developer might accidentally do:

app.post('/data', (req, res) => {
  const data = JSON.parse(req.body); // ❌ CRASHES HERE
  // handle data
});
Enter fullscreen mode Exit fullscreen mode

Result:

SyntaxError: Unexpected token o in JSON at position 1
Enter fullscreen mode Exit fullscreen mode

Because it's trying to parse something that's already parsed. It's like trying to turn a cake back into eggs and flour.

2. Real-World Crash Scenario

Let’s walk through what this looks like in production:

The Setup:

You’re running an Express.js API. The middleware is set up like this:

app.use(express.json());
Enter fullscreen mode Exit fullscreen mode

This automatically parses incoming Content-Type: application/json requests into JavaScript objects. So when the handler gets the request, req.body is already a usable object.

But a new developer on the team—or maybe your past self—adds:

const userInput = JSON.parse(req.body);
Enter fullscreen mode Exit fullscreen mode

Boom.

Now every valid request results in a crash, because the code is trying to parse an already-parsed object.

The Impact:

  • App crashes immediately.
  • No error handling catches it.
  • High latency or downtime for all users.
  • You get paged at 3 a.m. by your monitoring tool.
  • Blame is thrown around.

3. Why Is This So Common?

Because it’s deceptively simple.

  • Junior developers copy-paste from tutorials or Stack Overflow.
  • Middleware order isn’t understood well.
  • The difference between raw request body and parsed body isn’t always obvious.
  • JSON parsing feels so universal that we instinctively reach for JSON.parse().

Also, consider this: if the middleware isn't set up (or fails), then the lack of JSON.parse() is the problem. So now you’re either:

  • Parsing too early (when it’s already parsed), or
  • Not parsing at all (when you need to).

It’s a fragile edge.

4. Spotting the Crash: How I Caught It

In one audit I did for a startup’s Node.js API, they complained about random crashes after deployments, even though nothing major changed.

The smoking gun?

// utils/input.js
module.exports.parseInput = (body) => {
  return JSON.parse(body);
};
Enter fullscreen mode Exit fullscreen mode

This utility function was used everywhere in route handlers like:

const { parseInput } = require('./utils/input');
 
app.post('/form', (req, res) => {
  const formData = parseInput(req.body); 
});
Enter fullscreen mode Exit fullscreen mode

The team had recently introduced express.json(), but never updated the utility. So now, all incoming POST routes were crashing.

We fixed it by detecting the type before parsing:

function safeParseBody(body) {
  if (typeof body === 'string') {
    try {
      return JSON.parse(body);
    } catch (err) {
      console.error('Invalid JSON:', err.message);
      return null;
    }
  }
  return body;
}
Enter fullscreen mode Exit fullscreen mode

Lesson learned: Never assume the body is a string. Always check.

5. The Proper Way to Handle JSON in Node.js

Here’s a safe, modern approach using Express:

1. Use built-in middleware correctly

const express = require('express');
const app = express();
 
app.use(express.json()); // Automatically parses application/json
Enter fullscreen mode Exit fullscreen mode

This makes req.body always a usable object (assuming the client sends valid JSON).

2. Handle edge cases

Sometimes, the client might send invalid JSON, or no JSON at all. Use error-handling middleware:

app.use((err, req, res, next) => {
  if (err instanceof SyntaxError && err.status === 400 && 'body' in err) {
    return res.status(400).json({ error: 'Invalid JSON payload' });
  }
  next();
});
Enter fullscreen mode Exit fullscreen mode

3. Never manually parse if already parsed

Avoid this:

const data = JSON.parse(req.body); 
Enter fullscreen mode Exit fullscreen mode

Do this:

const data = req.body; //
Enter fullscreen mode Exit fullscreen mode

If you're unsure about the type:

const data = typeof req.body === 'string' ? JSON.parse(req.body) : req.body;
Enter fullscreen mode Exit fullscreen mode

6. Testing for It

Write automated tests that send both string and object payloads to your API and ensure your routes can handle both.

Example using Supertest:

const request = require('supertest');
 
it('handles valid JSON payload', async () => {
  await request(app)
    .post('/test')
    .send({ name: 'Test' })
    .expect(200);
});
 
it('handles invalid JSON payload gracefully', async () => {
  await request(app)
    .post('/test')
    .set('Content-Type', 'application/json')
    .send('{"broken": ') // invalid JSON
    .expect(400);
});
Enter fullscreen mode Exit fullscreen mode

7. Other Variants of the Same Problem

This issue isn’t limited to req.body. You’ll see similar bugs when:

  • Using fs.readFile and then JSON.parse() without checking if the file is already parsed.
  • Reading a file with .json extension via require() and then parsing it again.
  • Parsing localStorage.getItem() values in browser apps multiple times.

8. Bonus: Security Implications

Improper JSON parsing opens up security holes too.

JSON Parsing Attacks:

Attackers can craft requests with large JSON payloads that exhaust the server memory if you’re blindly parsing every request manually with JSON.parse().

Or they can break your API by sending Content-Type: text/plain which skips your JSON middleware and hits your manual parser directly—causing a crash.

Mitigate this with:

app.use(express.json({ limit: '100kb' })); // prevent large payloads
Enter fullscreen mode Exit fullscreen mode

9. Your JSON Safety Checklist

Before we wrap up, here’s a checklist to avoid this one-liner mistake in production:

→ Use express.json() middleware early in the stack.
→ Never parse req.body manually unless you have a reason.
→ Use content-type checks and validations.
→ Add error-handling middleware for SyntaxError.
→ Log suspicious or malformed payloads.
→ Set limits to prevent abuse.
→ Write automated tests for API input edge cases.
→ Don’t blindly copy-paste parsing code from tutorials.

Final Thoughts: Small Line, Big Impact

One line. That’s all it takes to break a high-performing Node.js backend.

And yet, this single line:

JSON.parse(req.body);
Enter fullscreen mode Exit fullscreen mode

…has likely caused more damage than a dozen serverless misconfigurations combined.

Don’t underestimate it.

The best Node.js developers aren’t the ones who write the most clever code—they’re the ones who know when not to write code that doesn’t belong.

** TL;DR**

  • Don’t manually parse req.body if you're already using express.json().
  • Use defensive coding and proper middleware setup.
  • One line of bad code can lead to massive outages.
  • Review every use of JSON.parse() in your codebase today.

You may also like:

  1. Top 10 Large Companies Using Node.js for Backend

  2. Why 85% of Developers Use Express.js Wrongly

  3. Top 10 Node.js Middleware for Efficient Coding

  4. 5 Key Differences: Worker Threads vs Child Processes in Node.js

  5. 5 Effective Caching Strategies for Node.js Applications

  6. 5 Mongoose Performance Mistakes That Slow Your App

  7. Building Your Own Mini Load Balancer in Node.js

  8. 7 Tips for Serverless Node.js API Deployment

  9. How to Host a Mongoose-Powered App on Fly.io

  10. The Real Reason Node.js Is So Fast

  11. 10 Must-Know Node.js Patterns for Application Growth

  12. How to Deploy a Dockerized Node.js App on Google Cloud Run

  13. Can Node.js Handle Millions of Users?

  14. How to Deploy a Node.js App on Vercel

  15. 6 Common Misconceptions About Node.js Event Loop

  16. 7 Common Garbage Collection Issues in Node.js

  17. How Do I Fix Performance Bottlenecks in Node.js?

  18. What Are the Advantages of Serverless Node.js Solutions?

  19. High-Traffic Node.js: Strategies for Success

Read more blogs from Here

You can easily reach me with a quick call right from here.

Share your experiences in the comments, and let's discuss how to tackle them!

Follow me on LinkedIn
 

Top comments (1)

Some comments may only be visible to logged-in visitors. Sign in to view all comments.