node.jsexpressurl-routingexpress-routerpath-to-regexp

Express 5 optional route parameters (:param?) throw PathError with path-to-regexp


I'm using Express 5.1.0 with Node.js v22.19.0, and I want to define a route where the parameter is optional, like /directory or /directory/someFolder.

Here's the code I tried:

import express from 'express';
import { readdir, stat } from 'node:fs/promises';

const app = express();

app.get('/directory/:foldername?', async (req, res) => {
  const { foldername } = req.params;
  const targetPath = foldername ? `./storage/${foldername}` : './storage';

  const fileList = await readdir(targetPath);
  const resData = [];
  for (const item of fileList) {
    const stats = await stat(`${targetPath}/${item}`);
    resData.push({ name: item, isDirectory: stats.isDirectory() });
  }

  res.json(resData);
});

app.listen(3000);

But when I run this, I get the following error:

PathError [TypeError]: Unexpected ? at index 20, expected end: /directory/:foldername?
    at consumeUntil (.../node_modules/path-to-regexp/dist/index.js:153:19)
    at parse (.../node_modules/path-to-regexp/dist/index.js:157:26)
    at pathToRegexp (.../node_modules/path-to-regexp/dist/index.js:267:58)
    ...
originalPath: '/directory/:foldername?'

What I've found so far:

I tried /directory/:foldername(*)? but that also throws Missing parameter name errors.

I expected the route /directory/:foldername? to let me hit both:

That's how it worked in Express 4.

But in Express 5.1.0, when I try this:

app.get('/directory/:foldername?', handler);

it immediately crashes with the PathError [TypeError]: Unexpected ? at index....

I also tried:

app.get('/directory/:foldername(*)?', handler);

but that throws a different error: Missing parameter name at index....


Solution

  • Express 5 uses curly braces ({ }) to denote optional path elements:

    app.get('/directory{/:foldername}', async (req, res) => {
        // Here -------^------------^