Latest Results
fix: rewrite selects the wrong dynamic route (#18078)
* Validate rewrite candidates to fix route pick
`findRouteToRewrite` committed to the first route whose pattern matched
the requested path. Its only rejection branch reads `route.distURL`,
which is populated only while a build writes files, so in `astro dev`
and for on-demand routes in a server build it could never run.
A rewrite to a path owned by a later dynamic route therefore failed
whenever an earlier dynamic route also matched the pattern. With
`src/pages/[category]/index.astro` returning no paths alongside
`src/pages/[...slug].astro`, `GET /alpha/` rendered but
`context.rewrite('/alpha/')` threw, because `/[category]` was selected
and owns nothing.
Candidates are now validated when `distURL` is unavailable, following
`matchRoute` closely: only `NoMatchingStaticPathFound` rejects a
candidate, a `getStaticPaths()` failure does not stop the search but is
rethrown if no candidate owned the path, and a caller that passes no
validator keeps the previous first-match behaviour.
* Add regression tests for overlapping route rewrite
Unit tests drive `findRouteToRewrite` directly to pin the selection
rules: skip a matching route that owns nothing, keep the first match
when it does own the path, fall back to 404 when none do, let a later
route win over an earlier one that throws, surface that error when
nothing else matched, and leave behaviour unchanged with no validator.
The dev-server test covers the case end to end. Its second assertion is
a control, proving an ordinary request to the same path always worked.
* Pin build output for the overlapping route fixture
A build populates `distURL`, so it takes the pre-existing fast path
rather than the new validation. Nothing asserted that, which left the
claim that build output is unchanged resting on inspection alone.
The fixture is now also built, and both the page the catch-all owns and
the rewrite that targets it are checked in the emitted HTML. These pass
before and after the fix, which is the point: they guard the path the
fix deliberately does not touch.
* Require rewrite validation to close the gap
Review feedback on #18078: an optional validator let a caller keep the first-match selection that caused the bug, and every environment already supplies one. The validator doc now describes only what the function returns; candidate iteration stays documented in findRouteToRewrite. Comments describe current behaviour rather than history.
* Test rewrite candidates via the real validator
Review feedback on #18078: the cases passed hand-written validate callbacks, so the shipped createRewriteRouteValidator and getProps were never exercised. They now build a manifest the way dev-match-fallthrough.test.ts does and use getStaticPaths modules that own, do not own, or throw.
* Drop integration test and shorten changeset
Review feedback on #18078: rewrites are routing, so the unit tests through the real validator are enough, and the changeset follows the contribution guide: one present-tense line on the user-visible fix. Latest Branches
0%
0%
0%
© 2026 CodSpeed Technology