Production deployment throws TypeError: Router.use() requires a middleware function

default discord avatar
KasparTr
7 months ago
6

Everything was running well in production but after developing and locally testing some changes, deployment to production threw, out of nowhere, the following error: TypeError: Router.use() requires a middleware function



Full trace:


error Command failed with exit code 1.
 at internal/main/run_main_module.js:17:47
 at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:75:12)
 at Function.Module._load (internal/modules/cjs/loader.js:790:12)
 at Module.load (internal/modules/cjs/loader.js:950:32)
 at Object.Module._extensions..js (internal/modules/cjs/loader.js:1114:10)
 at Module._compile (internal/modules/cjs/loader.js:1085:14)
 at Object.<anonymous> (/home/node/dist/server.js:51:8)
 at Function.use (/home/node/node_modules/express/lib/router/index.js:462:11)
TypeError: Router.use() requires a middleware function

 ^
 throw new TypeError('Router.use() requires a middleware function')
/home/node/node_modules/express/lib/router/index.js:462


Because I didn't make any fundamental changes and all works well locally, it's quite a mystery where this opaque error comes from.



Has anybody had a similar problem in production?



The only place where Router.use() function is used is in server.ts file and that hasn't changed in the recent update.



server.ts


import payload from 'payload';
...
const router = express.Router();
router.use(payload.authenticate);
...
  • default discord avatar
    Martin R
    7 months ago

    Do you want to create a new Router? express.Router(); returns a New Router Object. Instead, you can add the middleware directly to express.



    const app = express();
    const yourMiddleware = (req, res, next) => {
        
        next();
    };
    
    app.get("/", (_, res) => {    res.redirect("/admin");  });
    app.use(yourMiddleware);
  • default discord avatar
    KasparTr
    7 months ago

    No, I haven't changed anything nor do I wish to change anything about this. It hasn't changed but the server failed to build this with any further new build. Even when I restored everything back to previously working code, the server now just doesn't run. Looks like a hosting provider issue?



    Solved. Turns out it was the Payload npm package.


    I was using the following version notation

    "payload": "^1.4.1"

    meaning all latest minor changes will be used.



    Between now and 24 days ago since I last built a new image, something has changes in the way PayloadCMS works with Express and although it claims to be a

    minor

    change, it was a breaking change and something in the

    server.ts

    file related with express needs to be re-written.



    I don't have time to do it now, so I reverted to using a strict version (1.4.1) of payload and it works. As soon as I use anything modern, it breaks.



    I want to have my own custom routes (e.g. health check, and others) and I also need to access payload authentication middleware inside them.


    So I followed tutorials on this but this doesn't work anymore in latest payload versions.



    Here is my server.ts new router related code.



      
      const router = express.Router();
      router.use(payload.authenticate);
    
      router.post('/transactions/process', (req: any, res) => {
        if (req.user) {
          return res.send(`Authenticated successfully as ${req.user.email}.`);
        }
        return res.send('Not authenticated');
      });
    
      router.get('/health', (req: any, res) => {
        res.send('Healthy')
      });
    
      app.use('/custom', router);
      app.listen(3000);
  • default discord avatar
    Martin R
    7 months ago

    It works if await payload.init is before payload.authenticate.



    const start = async () => {
      const router = express.Router();
      
      await payload.init({...}); // Changed to async. Need to wrap code into an async function
    
      router.use(payload.authenticate);
    
      router.post('/transactions/process', (req: any, res) => {
        if (req.user) {
          return res.send(`Authenticated successfully as ${req.user.email}.`);
        }
        return res.send('Not authenticated');
      });
    
      router.get('/health', (req: any, res) => {
        res.send('Healthy')
      });
    
      app.use('/custom', router);
      app.listen(3000);
    }
    
    start();
  • default discord avatar
    Adroit
    6 months ago

    Same problem here.

Open the post
Continue the discussion in Discord
Like what we're doing?
Star us on GitHub!

Star

Connect with the Payload Community on Discord

Discord

online

Can't find what you're looking for?

Get help straight from the Payload team with an Enterprise License.