DEV Community

Cover image for Fix: Cannot set headers after they are sent to the client
collegewap
collegewap

Posted on • Edited on • Originally published at codingdeft.com

Fix: Cannot set headers after they are sent to the client

If you are new to Node.js and express, you might have come across the following error:

Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
Enter fullscreen mode Exit fullscreen mode

In this article, we will discuss the possible causes of the error and how to fix them.

Consider the following code:

app.get("/api/orders/:orderId", function (req, res) {
  if (!req.params.orderId.match(/[0-9]+/)) {
    res.status(400).send({
      error: "Order id is invalid",
    })
  }

  // some other code..

  res.send({
    // order details
  })
})
Enter fullscreen mode Exit fullscreen mode

At first look, the code looks perfectly fine. But when we run the code by passing a string in the place of the orderId (/api/orders/abcd), you will get the error Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client.

The above error is occurring because when the order id is not a number, we are calling res.send() twice. Though res.send() sends the response back to the client, the code execution doesn't stop there. It continues with the execution of the remaining code and tries to return the response again to the client, hence the error.

We can fix this either by wrapping the rest of the code in an else block or adding a return at the end of the error handling:

app.get("/api/orders/:orderId", function (req, res) {
  if (!req.params.orderId.match(/[0-9]+/)) {
    res.status(400).send({
      error: "Order id is invalid",
    })
  } else {
    res.send({
      // order details
    })
  }
})
Enter fullscreen mode Exit fullscreen mode

OR

app.get("/api/orders/:orderId", function (req, res) {
  if (!req.params.orderId.match(/[0-9]+/)) {
    res.status(400).send({
      error: "Order id is invalid",
    })
    return
  }
  res.send({
    // order details
  })
})
Enter fullscreen mode Exit fullscreen mode

Another scenario where this error could occur is while you make a res.send() call after a promise is resolved.

async function stall(stallTime = 3000) {
  await new Promise(resolve => setTimeout(resolve, stallTime))
}

app.get("/api/invoice/:invoiceId", function (req, res) {
  stall().then(() => {
    res.send({
      // invoice details
    })
  })

  // Some other code
  res.send({
    //some other data
  })
})
Enter fullscreen mode Exit fullscreen mode

The fix for the above code is to carefully add conditions and ensure that res.send() is called only once per each scenario.

Top comments (1)

Collapse
 
carlosridg profile image
carlosridg

The error message "Can't set headers after they are sent" commonly occurs in Node.js applications when attempting to modify response headers after the response has already been sent to the client. This error typically indicates a logic issue where multiple responses are being sent or headers are being set too late in the code execution. To resolve this error, ensure that response headers are set before sending the response and that only a single response is sent per request, avoiding any modifications to headers after the response has been sent.

If you're using middleware in your application, particularly ones that modify the response headers, ensure that they are properly ordered. Middleware functions are executed in the order they are defined, so if a response is sent before a middleware function attempts to modify headers, the error can occur. Make sure the middleware that sets headers is placed before the middleware that sends the response. Also, When sending a response, ensure that you properly exit from the function or block of code. Use return statements or appropriate flow control mechanisms to prevent subsequent execution that may attempt to modify headers.