Skip to content

Route matching behaves unexpectedly with non-trailing rest params with a matcher #15204

@WarningImHack3r

Description

@WarningImHack3r

Describe the bug

I have the following structure:

src/routes/
└ [...a=m]/
  ├ +page.server.ts
  └ [b]/
    ├ +page.server.ts
    └ [c]/
      └ +page.server.ts
...

Other than this part, I only have named routes.

My matcher m only matches a single case: return param.replace(/^https?:\/\/?/, "") === "github.com" (that's the reason why I need a to be a rest param: it needs to be able to optionally match https:// or https:/ in front of github.com, effectively being able for a to contain ["https:", "", "github.com"]).

The thing is, /robots.txt (or any other nonexistent request) unexpectedly gets caught by [b]/+page.server.ts, despite m explicitely returning false. The outcome params object from [b] is { a: '', b: 'robots.txt' }.

I get that the rest param is optional and can therefore catch "nothing", but this shouldn't be the case when it has a matcher attached, and this very matcher explicitly returns false. This is even documented in the docs:

src/routes/a/[...rest]/z/+page.svelte will match /a/z (i.e. there’s no parameter at all) as well as /a/b/z and /a/b/c/z and so on. Make sure you check that the value of the rest parameter is valid, for example using a matcher.

Reproduction

https://stackblitz.com/edit/sveltejs-kit-template-default-6mviucz9?file=src%2Froutes%2F%5B...a%3Dm%5D%2F%5Bb%5D%2F%2Bpage.svelte (visit /robots.txt)

Logs

System Info

System:
    OS: macOS 26.2
    CPU: (10) arm64 Apple M1 Pro
    Memory: 91.14 MB / 16.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 25.4.0 - /opt/homebrew/bin/node
    npm: 11.8.0 - /opt/homebrew/bin/npm
    pnpm: 10.28.0 - /opt/homebrew/bin/pnpm
    bun: 1.3.6 - /Users/antoine/.bun/bin/bun
    Deno: 2.6.6 - /opt/homebrew/bin/deno
  Browsers:
    Chrome: 137.0.7151.120
    Firefox: 145.0.1
    Safari: 26.2
    Safari Technology Preview: 26.0
  npmPackages:
    @sveltejs/adapter-vercel: ^6.3.0 => 6.3.0
    @sveltejs/kit: ^2.49.5 => 2.49.5
    svelte: ^5.46.4 => 5.46.4
    vite: ^7.3.1 => 7.3.1

Severity

annoyance

Additional Information

This can be bypassed by creating a new route /[...catchall] with a +page.server.ts throwing an explicit 404:

// src/routes/[...catchall]/+page.server.ts
import { error } from "@sveltejs/kit";

export function load() {
	error(404);
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions