[▲ Vercel Community](/) · [Categories](/categories) · [Latest](/latest) · [Top](/top) · [Live](/live)

[Help](/c/help/9)

# revalidatePath fails to invalidate Next.js catch-all routes on Vercel

35 views · 1 like · 2 posts


Greg Orjan (@greg-orjan) · 2026-03-12

`revalidatePath` does not invalidate pages when using optional catch-all routes `[[...path]]` with dynamic locales.

## Reproduction Steps

1.  Navigate to [https://revalidate-issues.vercel.app](https://revalidate-issues.vercel.app)
2.  Note the current timestamp on `/fr` page
3.  Call the revalidate API:
    
```bash
curl -X POST https://revalidate-issues.vercel.app/api/revalidate -H 'Content-Type: application/json' -d '{"path": "/fr"}'
```
        
4.  Refresh the page
5.  The timestamp remains unchanged - revalidation did not work

## Additional Notes

*   `revalidate = false` is set (dynamic rendering)
*   `dynamic = 'error'` forces dynamic rendering
*   Only "en" is in `generateStaticParams`; "fr" is intentionally omitted
*   The issue affects only locales not listed in `generateStaticParams`
*   The issue does not affect subpages like `/fr/about-us`
*   The issue is only in Vercel environment; on local machine it works as expected

## Expected Behavior

Calling `revalidatePath('/fr')` should invalidate the cache for that path, causing a fresh render on next visit.

## Observed Behavior

The timestamp does not change after calling `revalidatePath`, indicating the page is served from cache.

**Code:** [https://github.com/gregorjan/revalidate-issues](https://github.com/gregorjan/revalidate-issues)

**Deployed App:** [https://revalidate-issues.vercel.app](https://revalidate-issues.vercel.app)


Jacob Paris (@jacobparis) · 2026-03-12 · ♥ 1

Thanks for the detailed reproduction! This is fixed in the latest next.js canary build and should make it into a stable release soon. I see you also made a support ticket and you'll get a reply on that as well

When you added "en" to generateStaticParams, it actually created an ISR route for that path at `/en` which matched directly and skipped resolving the catch all route entirely, so that route kind of just worked by coincidence 

The real bug was that revalidation wasn't working properly with empty optional catch alls 

As immediate fixes
- Based on the bug I think it will work if you add a trailing slash like `revalidatePath('/fr/')`
- but if not a custom cacheTag()/revalidateTag() pair should serve as a substitute until this lands in a stable version if you need to wait for that