From 609fdb7d26ceb0e2350db31af69ff311c2d371f7 Mon Sep 17 00:00:00 2001 From: Elliott Johnson Date: Tue, 27 Jan 2026 16:42:12 -0700 Subject: [PATCH] fix: only match rest params with matchers when the matcher matches --- .changeset/spotty-bears-doubt.md | 5 +++++ packages/kit/src/utils/routing.js | 8 ++++++-- packages/kit/src/utils/routing.spec.js | 20 ++++++++++++++++++++ 3 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 .changeset/spotty-bears-doubt.md diff --git a/.changeset/spotty-bears-doubt.md b/.changeset/spotty-bears-doubt.md new file mode 100644 index 000000000000..48fbcee1c7ca --- /dev/null +++ b/.changeset/spotty-bears-doubt.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': patch +--- + +fix: only match rest params with matchers when the matcher matches diff --git a/packages/kit/src/utils/routing.js b/packages/kit/src/utils/routing.js index f36988f370b8..ca8e9fc3b345 100644 --- a/packages/kit/src/utils/routing.js +++ b/packages/kit/src/utils/routing.js @@ -162,8 +162,12 @@ export function exec(match, params, matchers) { // if `value` is undefined, it means this is an optional or rest parameter if (value === undefined) { - if (param.rest) result[param.name] = ''; - continue; + if (param.rest) { + // We need to allow the matcher to run so that it can decide if this optional rest param should be allowed to match + value = ''; + } else { + continue; + } } if (!param.matcher || matchers[param.matcher](value)) { diff --git a/packages/kit/src/utils/routing.spec.js b/packages/kit/src/utils/routing.spec.js index 75f5487eb2fa..8434e83839ae 100644 --- a/packages/kit/src/utils/routing.spec.js +++ b/packages/kit/src/utils/routing.spec.js @@ -245,6 +245,26 @@ describe('exec', () => { path: '/a/b/c', expected: undefined }, + { + route: '/[...a=doesntmatch]/[b]', + path: '/foo', + expected: undefined + }, + { + route: '/[...a=matches]/[b]', + path: '/foo', + expected: { a: '', b: 'foo' } + }, + { + route: '/[...a=doesntmatch]/[b]/[c]', + path: '/foo/bar', + expected: undefined + }, + { + route: '/[...a=matches]/[b]/[c]', + path: '/foo/bar', + expected: { a: '', b: 'foo', c: 'bar' } + }, { route: '/[...catchall]', path: '/\n',