Middleware rewrite target route resolution uses wrong priority
#1,331 opened on May 20, 2026
Repository metrics
- Stars
- (8,563 stars)
- PR merge metrics
- (Avg merge 1d 1h) (462 merged PRs in 30d)
Description
This issue was created by an agent analysing CI failures from the Next.js Deploy Suite (vinext
mainvs Next.jsv16.2.6, 2026-05-20).
Problem
After middleware rewrites a request URL, the rewritten path is matched against the route table with incorrect priority. Dynamic catch-all routes ([id]/[slug]) capture the rewrite target instead of resolving to the correct static or named page.
For example, when middleware rewrites /rewrite-1 to /:
- Expected: The home page renders ("Hello World")
- Actual: The
[id]dynamic route captures it, rendering "Dynamic route" withquery.id = "rewrite-1"
Expected substring: "Hello World"
Received string: "...<p class=\"title\">Dynamic route</p>..."
This also affects:
- Rewrites to named pages like
/about(renders[id]instead) - External rewrites (to
example.com) resulting in 404 instead of proxying fallback: truepages rendering full data immediately instead of the fallback/loading state
Estimated Impact
~35 test failures across the deploy suite.
Affected Test Suites
test/e2e/middleware-trailing-slash/test/index.test.ts(~10 failures)test/e2e/middleware-rewrites/test/index.test.ts(~12 failures)test/e2e/basepath/redirect-and-rewrite.test.tstest/e2e/app-dir/app-middleware-proxy/app-middleware-proxy.test.ts
Recommendation
-
Reproduce first in vinext's own test suite. Add a test case with a middleware that rewrites to a known static page and a dynamic
[id]route. Assert the static page renders, not the dynamic route. Confirm it fails. -
Study Next.js route matching after rewrites. In Next.js, after a middleware rewrite, the rewritten URL is re-matched against the full route table with proper priority: static routes > predefined dynamic routes > catch-all routes. Search
.nextjs-ref/packages/next/src/server/for how post-rewrite matching works. -
Fix the post-rewrite route matcher. The rewritten path should go through the full filesystem route resolution, not just dynamic route matching. Static routes and named pages must take priority over dynamic catch-alls.
-
Implement external URL proxying for rewrites. When middleware rewrites to an absolute external URL (e.g.,
https://example.com), the server should proxy the request to that URL and return the response, rather than matching it against local routes. -
Check dev/prod parity. Ensure the fix applies to both
server/dev-server.tsandserver/prod-server.ts.