Search code examples
node.jsexpress

stream.listeners is not a function


Trying to run a really basic Express app, I'm getting this error:

/path/to/testserver/node_modules/unpipe/index.js:22
  var listeners = stream.listeners('data')
                         ^

TypeError: stream.listeners is not a function
    at hasPipeDataListeners (/path/to/testserver/node_modules/unpipe/index.js:22:26)
    at unpipe (/path/to/testserver/node_modules/unpipe/index.js:52:8)
    at send (/path/to/testserver/node_modules/finalhandler/index.js:311:3)
    at /path/to/testserver/node_modules/finalhandler/index.js:133:5
    at Function.handle (/path/to/testserver/node_modules/express/lib/application.js:177:5)
    at app (/path/to/testserver/node_modules/express/lib/express.js:39:9)
    at file:///path/to/testserver/index.js:6:1
    at ModuleJob.run (node:internal/modules/esm/module_job:193:25)
    at async Promise.all (index 0)
    at async ESMLoader.import (node:internal/modules/esm/loader:530:24)

The app code is literally just:

import express from "express";

const port = 3000;
const app = express();

app("/", (req, res) => {
    res.send("Is this thing on?");
});

app.listen(port, () => {
    console.log(`Listening on ${port}...`);
});

I bootstrapped the project like this:

npm init -y
npm install express

...and then added "type": "module" to package.json (but I know the problem isn't ESM; I removed that and switched to require and had the same problem).

Why am I getting that error? I don't see that error message in the issues list.


Solution

  • It's a typo-level mistake, but the symptom is so bizarre and the typo so subtle that it's worth having an answer about it here. The problem is here:

        app("/", (req, res) => {
    //  ^^^^−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
            res.send("Is this thing on?");
        });
    

    That calls app. The code should be calling one of app's methods, like app.get:

        app.get("/", (req, res) => {
    //  ^^^^^^^^−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
            res.send("Is this thing on?");
        });
    

    Although it doesn't seem to be documented, app (the function) calls app.handle. From node_modules/express/lib/express.js:

    var app = function(req, res, next) {
      app.handle(req, res, next);
    };
    

    app.handle expects very different parameters than app.get does. It happens that passing it app.get parameters takes it down a path to where eventually it reaches that error condition.

    Just change app( to app.get( or whatever other method the code was meant to use.