'How to solve : Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client

I have a node/express server code as

index.js

const express = require("express");
const Room = require("./models/room");
const roomRouter = require("./routes/room");
require("./models/db");
const cors = require("cors");

const port = process.env.PORT || 5000;

const app = express();

const server = require("http").createServer();

app.use(express.json());
app.use(roomRouter);

const io = require("socket.io")(server, {
  cors: {
    origin: "http://localhost:3000",
    methods: ["GET", "POST"],
  },
});

// const io = require("socket.io")(server);

app.get("/", (req, res) => {
  res.send("hello world");
});

app.use((req, res, next) => {
  res.setHeader("Access-Control-Allow-Origin", "*");
  res.setHeader("Access-Control-Allow-Credentials", "true");
  res.setHeader("Access-Control-Max-Age", "1800");
  res.setHeader("Access-Control-Allow-Headers", "content-type");
  res.setHeader(
    "Access-Control-Allow-Methods",
    "PUT, POST, GET, DELETE, PATCH, OPTIONS"
  );
  next();
});
app.use(cors());

io.on("connection", (socket) => {
  console.log("Connected");

  const id = socket.handshake.query.id;
  socket.join(id);

  socket.on("roomCreated", async (roomId) => {
    console.log("Room created with id of " + roomId);
    const isRoomExist = await Room.findOne({ roomId });
    if (isRoomExist) return;
    const room = await Room({ roomId });
    await room.save();
  });
});

server.on("request", app);

server.listen(port, () => {
  console.log("running on 5000");
});

I am using socket io and i want to send request from localhost:3000, that's why I needed to allow CORS option. So I wrote the code above. But as soon as I run the server, it throws me error that says,

Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
    at new NodeError (node:internal/errors:371:5)
    at ServerResponse.setHeader (node:_http_outgoing:576:11)
    at expressInit (B:\projects\typingtestserver\node_modules\express\lib\middleware\init.js:30:42)
    at Layer.handle [as handle_request] (B:\projects\typingtestserver\node_modules\express\lib\router\layer.js:95:5)
    at trim_prefix (B:\projects\typingtestserver\node_modules\express\lib\router\index.js:323:13)
    at B:\projects\typingtestserver\node_modules\express\lib\router\index.js:284:7
    at Function.process_params (B:\projects\typingtestserver\node_modules\express\lib\router\index.js:341:12)
    at next (B:\projects\typingtestserver\node_modules\express\lib\router\index.js:275:10)
    at query (B:\projects\typingtestserver\node_modules\express\lib\middleware\query.js:45:5)
    at Layer.handle [as handle_request] (B:\projects\typingtestserver\node_modules\express\lib\router\layer.js:95:5)
node:_http_outgoing:576
    throw new ERR_HTTP_HEADERS_SENT('set');
    ^

Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
    at new NodeError (node:internal/errors:371:5)
    at ServerResponse.setHeader (node:_http_outgoing:576:11)
    at ServerResponse.writeHead (node:_http_server:308:21)
    at respond (B:\projects\typingtestserver\node_modules\engine.io\build\transports\polling.js:242:22)
    at Polling.doWrite (B:\projects\typingtestserver\node_modules\engine.io\build\transports\polling.js:247:13)
    at Polling.write (B:\projects\typingtestserver\node_modules\engine.io\build\transports\polling.js:221:14)
    at doWrite (B:\projects\typingtestserver\node_modules\engine.io\build\transports\polling.js:203:18)
    at B:\projects\typingtestserver\node_modules\engine.io-parser\build\cjs\index.js:19:17
    at encodePacket (B:\projects\typingtestserver\node_modules\engine.io-parser\build\cjs\encodePacket.js:10:12)
    at B:\projects\typingtestserver\node_modules\engine.io-parser\build\cjs\index.js:16:39 {
  code: 'ERR_HTTP_HEADERS_SENT'
}

P.S. when I open localhost:5000 it is showing "Hello world".

EDITED:

code for roomRouter:

routes/room.js

const express = require("express");
const Room = require("../models/room");

const router = express.Router();

router.post("/checkId", async (req, res) => {
  console.log("got post request");
  const { roomId } = req.body;
  if (!roomId) res.json({ success: false, message: "No room id typed1" });

  try {
    const room = await Room.findOne({ roomId });

    if (room) res.json({ success: true, message: "Found the room" });
    else res.json({ success: false, message: "Didn't find the room" });
  } catch (err) {
    res.json({
      success: true,
      message: "Error in finding room. Try entering id again",
    });
  }
});

module.exports = router;

models/room.js

const mongoose = require("mongoose");

const PlayerSchema = new mongoose.Schema(
  {
    username: {
      type: String,
      required: true,
    },
    ishost: {
      type: Boolean,
      default: false,
      required: true,
    },
  },
  { timestamps: true }
);

const RoomSchema = new mongoose.Schema(
  {
    roomId: {
      type: String,
      required: true,
    },
    players: [PlayerSchema],
  },
  { timestamps: true }
);

module.exports = mongoose.model("Room", RoomSchema

);



Solution 1:[1]

SOLVED:

In index.js file I was using server.on("request", app), and this turned out to be problematic for some reason that I don't know about. Problem is solved after using removing that line and using const server = require("http").createServer(app); instead of const server = require("http").createServer();

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Sachin Bhusal