Skip to content

Restore Support for app.all('*') Wildcard in Express v5 #6711

Open

Description

@Tanmay-008

❗ Description:

In Express v5.1.0, routes using app.all('*') (or similar wildcard syntax) fail with:

Error 👹: throw new TypeError(Missing parameter name at ${i}: ${DEBUG_URL});

This change comes from stricter path-to-regexp parsing rules.
In Express v4, the following code worked fine:

app.all('*', (req, res) => res.send('Not Found'));

But in Express v5, developers are forced to write:

app.all('/*splat', (req, res) => res.send('Not Found'));
// or
app.all('/{*splat}', (req, res) => res.send('Not Found'));

This breaks a very common catch-all route pattern used widely in v4 projects.

🔍 Root Cause

1.Express v5 migrated to a stricter version of path-to-regexp.

2.Unnamed wildcards (*) are no longer allowed.

3.Developers must now explicitly name the wildcard parameter.

✅ Expected Behavior

Express v5 should either:

Gracefully support app.all('*') as a valid catch-all syntax (to maintain backward compatibility).

Or, if strict syntax is required:

Provide a clearer error message explaining the new requirement.

Update docs & migration guide to emphasize the change prominently.

📌 Suggested Fixes

Restore legacy * wildcard syntax support (backward compatibility).

Or provide an explicit alternative (e.g. app.all('/*')) documented as the replacement.

Improve error messaging in path-to-regexp.

🔗 Related Issue

This request builds upon Issue #6664 where the problem was first reported. Maintainers clarified that this is not a bug but an intentional change — hence this formal feature request.

Activity

  1. mihaijulien commented on Aug 18, 2025

    @mihaijulien

    This was a very annoying "breaking" change.

  2. adiantek commented on Aug 22, 2025

    @adiantek

    is there any workaround?

  3. bjohansebas commented on Aug 23, 2025

    @bjohansebas
    Member

    I really don’t know why the change was made and I’m not sure if reverting it would imply a breaking change.

    cc: @blakeembrey

  4. SergioNR commented on Aug 23, 2025

    @SergioNR

    Although it is not the intended usage, a workaround is using app.use(‘*fallback’, req, res => { res.send(‘not found’} )

    At least that’s what I’m using for catch all routes

  5. bjohansebas commented on Aug 23, 2025

    @bjohansebas
    Member

    Actually, this is how it should be used in this version, the functionality was never removed, it's just that now it needs to be named. Please check the migration guide (https://expressjs.com/en/guide/migrating-5#path-syntax).

    What I understand is that they want it to go back to how it was before, without having to name it.

  6. Tanmay-008 commented on Aug 23, 2025

    @Tanmay-008
    Author

    (@bjohansebas )When we use (app.all('*', (req, res) => res.send('Not Found')); ) we get the error:(throw new TypeError(Missing parameter name at ${i}: ${DEBUG_URL}); ). Can we update this? Because the error message does not explain anything clearly. It should be something that, when read, the user can understand what needs to be updated.Basically for beginners.

  7. blakeembrey commented on Aug 23, 2025

    @blakeembrey
    Member

    @Tanmayshi Could you provide an example message of what could help you or someone else understand has broken better? I have a release ready that marginally improves this, but it isn’t a rewrite to the message, so it could still use your input to make it better.

  8. SergioNR commented on Aug 23, 2025

    @SergioNR

    @Tanmayshi , from what I ve gathered from the docs, app.all() should not be used to handle global catch all routers, but app.use() instead. Maybe someone more knowledgeable can provide their insight too

    App.all() should be used when any req method should return the same response on any given endpoint - eg:

    GET /health
    POST /health

    Should both return status 200

  9. Tanmay-008 commented on Aug 24, 2025

    @Tanmay-008
    Author

    (@blakeembrey )You could make the message a bit more beginner-friendly so it’s easier to understand. Most beginners use Express, and the current message doesn’t really feel aligned with that perspective.

  10. krzysdz commented on Aug 24, 2025

    @krzysdz
    Contributor

    You could make the message a bit more beginner-friendly so it’s easier to understand.

    pillarjs/path-to-regexp#363 will improve the message. It's been already merged and should be in the next path-to-regexp release.

  11. blakeembrey commented on Aug 24, 2025

    @blakeembrey
    Member

    @Tanmayshi I understand you want it to be beginner friendly, I’m hoping to understand what would have helped you solve this. I hope it’s clear that I tried to make the errors friendly to begin with, and included a URL you could open to read more, in an attempt to make it beginner friendly already but it doesn’t seem to be enough.

  12. alandsidel commented on Aug 30, 2025

    @alandsidel

    Ran into this myself today when updating an old project. I believe this change was a bad idea and can't intuitively see a reason to make *splat a special token; it seems like simply adding * as the special token would have worked just as well; a plain * with nothing preceding it is not a valid regex.

    That said, I agree the error messaging needs improvement. The message I saw is:

    Uncaught Exception: TypeError: Missing parameter name at 1: https://git.new/pathToRegexpError followed by a backtrace which doesn't lead to my code. As a dev this is immediately problematic, as at first glance it looks like some bug in the library or incompatibility between dependencies. The impression is that the problem isn't actually in my code.

    Furthermore the URL https://git.new/... does not appear legitimate at first glance (I've never seen the .new TLD before now) and looks like some kind of internal path. Since it just redirects to a github.com URL anyway, that URL should probably be used instead.

    As the URL leads to a pillarjs repo page, I was further mislead into believing this was some kind of internal library error, as I do not use pillarjs or path-to-regexp and had not heard of it before now. There is no indication in the error shown or documentation that this has anything to do with my code, or with express which I would at least have recognized.

    The documentation at that link states:

    Missing parameter name
    Parameter names must be provided after : or *, and they must be a valid JavaScript identifier. If you want an parameter name that isn't a JavaScript identifier, such as starting with a number, you can wrap the name in quotes like :"my-name".

    This also does not mention express.

    Ultimately I had to just dig through everywhere in my code where I was using * as some kind of parameter, change/comment it, and see if the error went away. This allowed me to narrow the issue down to express, and then to find this discussion.

  13. blakeembrey commented on Sep 2, 2025

    @blakeembrey
    Member

    Thank you @alandsidel, this is very helpful. I just released path-to-regexp@8.3.0 (which will automatically pull into new installs) because I didn't see any additional feedback on improving help but it comes with some changes that should help debug in the future:

    1. It says visit http://... for more info so it's more obviously somewhere to click
    2. It reduced the stack size internally to be 4 lines (so it should trace back to your application properly now)

    As the URL leads to a pillarjs repo page

    I wonder if it makes sense to try..catch the error in express or router and redirect to express docs? @wesleytodd @expressjs/express-tc Alternatively it could be a config option so you can inject it into the library error.

  14. alandsidel commented on Sep 2, 2025

    @alandsidel
    1. It says visit http://... for more info so it's more obviously somewhere to click

    It does, but it still looks incorrect/suspicious/weird, and we all should know better than to click on suspicious looking links, so I didn't until after I'd solved it and was writing my comment to see if it was actually real or not. :)

    1. It reduced the stack size internally to be 4 lines (so it should trace back to your application properly now)

    This worked. I deleted package-lock.json and node_modules for a project using express 5.1.0 and reran npm i. package-lock.json says it pulled in path-to-regexp 8.3.0.

    I put the old app.get('*'...) back in and it does now reference the correct line in my source file, so that's a big help.

    As the URL leads to a pillarjs repo page

    I wonder if it makes sense to try..catch the error in express or router and redirect to express docs? @wesleytodd @expressjs/express-tc

    Yeah maybe? That was a tough one for me so I didn't really have a good suggestion here.

    I do still think that a plain * should be regarded as a special token like *splat as it's not a valid regex pattern itself, since it has no preceding character identifier. Wasn't the change made in order to allow regex patterns? Maybe checking to see if the pattern is a valid regex and if it's not, then do the check for these types of reserved words?

    Stabbing in the dark there a bit.

  15. blakeembrey commented on Sep 2, 2025

    @blakeembrey
    Member

    It does, but it still looks incorrect/suspicious/weird

    That's fair, I can update it in another release. The .new domain is often used by Google and others, e.g. docs.new. I used a redirect to avoid breaking the link unexpectedly for past releases, in case the docs were moved.

    Wasn't the change made in order to allow regex patterns?

    Not exactly, it was changed for better compatibility with the ecosystem of proxies and path rewriting, e.g. rewrite /api/*path to /api/v1/*path. There were also many edge cases in the Express 4 path routing due to * being confused with writing a regular expression (e.g. \d* would expand to \d.*) but that's less of an issue now the entire string isn't a magic regex.

    Arguably it's better to have these be an error during the upgrade than to behave differently, but that's a separate can of worms since you could have written \d by itself and it's not behaving like a regex anymore. The error is only on modifiers like +, *, ?, [, and ].

    I do still think that a plain * should be regarded as a special token like *splat as it's not a valid regex pattern itself

    I'm not sure I understand this sentence, sorry. Can you clarify? There's no reserved words so I think maybe there's a miscommunication.

  16. trymeouteh commented on Jan 23, 2026

    @trymeouteh

    Please bring back *. It make the code simple to read.

    I cannot yet make the new wildcard paths work with my code since I have upgraded.

  17. Muhammad-Rahim-2024 commented on Feb 14, 2026

    @Muhammad-Rahim-2024

    i tried in express v5 latest and app.get("/{splat}" is the only one that works for me
    these dont work : app.get("/
    " , app.get("*" ,

  18. alandsidel commented on Mar 7, 2026

    @alandsidel

    I do still think that a plain * should be regarded as a special token like *splat as it's not a valid regex pattern itself

    I'm not sure I understand this sentence, sorry. Can you clarify? There's no reserved words so I think maybe there's a miscommunication.

    I'm referring to the special token *splat. I don't really know how to make that more clear?

    app.get('/*splat', .... does not literally match the url path /*splat, it matches what * used to match before this change.

  19. krzysdz commented on Mar 7, 2026

    @krzysdz
    Contributor

    I'm referring to the special token *splat. I don't really know how to make that more clear?

    *splat is not a special token. * introduces a wildcard parameter, which now must be named like : parameters. You can use /*literlallyAnythingThatYouWantAsLongAsItIsAValidIdentifier instead of /*splat. Both : and * capture values that can be accessed using req.params. The parameter name (e.g splat) that follows the * or : is the key name that will be present in req.params.

  20. alandsidel commented on Mar 7, 2026

    @alandsidel

    I'm referring to the special token *splat. I don't really know how to make that more clear?

    *splat is not a special token. * introduces a wildcard parameter, which now must be named like : parameters. You can use /*literlallyAnythingThatYouWantAsLongAsItIsAValidIdentifier instead of /*splat. Both : and * capture values that can be accessed using req.params. The parameter name (e.g splat) that follows the * or : is the key name that will be present in req.params.

    Ah, I see.

    Well, IMNSHO the singular * should still be treated as it always was. My understanding is that currently it doesn't mean anything, correct? It's just an invalid wildcard? Falling back to treating it the way it was always treated historically strikes me as the right choice here.

  21. mayfield commented on Oct 5, 2026

    @mayfield

    Finally updating to v5, and this is hands down the most annoying part so far. All the other changes feel well founded but this one does not.

    Wanting to apply effects to all OPTIONS requests for example.. Option 1: route.options('{/*foobar}', ...) and Option 2: route.options(/.*/, ...) is having to pick the lesser of two evils. The first form is ugly, the second form makes me cringe that I'm having to use regexp syntax for a function call that I'd prefer to be as branchless as possible. Even if the underlying resolution is identical in terms of branches it feels wrong and overly opinionated to force me to choose between nonsense words and having to write regular expressions. It's neither beginner friendly nor elegant.

  22. ardenash commented on Oct 5, 2026

    @ardenash
  23. alandsidel commented on Oct 5, 2026

    @alandsidel
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions