Skip to content

[config] Convert path-to-regexp patterns to regex in Route output#15134

Merged
MatthewStanciu merged 3 commits intomainfrom
matthew/convert-routes-regexp
Feb 19, 2026
Merged

[config] Convert path-to-regexp patterns to regex in Route output#15134
MatthewStanciu merged 3 commits intomainfrom
matthew/convert-routes-regexp

Conversation

@MatthewStanciu
Copy link
Copy Markdown
Contributor

@MatthewStanciu MatthewStanciu commented Feb 19, 2026

I was digging into a customer-reported issue where a customer's rewrites stopped working when they added a header transform using vercel.ts.

After digging on it I realized that when we don't convert path-to-regexp patterns to proper regex when compiling routes.rewrite() to the routes format. So it gets compiled to this:

{
  "src": "^/api/proxy/:path*$",
  "dest": "https://api.example.com/:path*",
  "transforms": [...]
}

When it should look like this:

{
  "src": "^/api/proxy(?:/((?:[^/]+?)(?:/(?:[^/]+?))*))?$",
  "dest": "https://api.example.com/$1",
}

So the route returns a 404 because it's trying to literally serve :path. This isn't an issue for rewrites defined in the rewrites property of vercel.json because those use the path-to-regexp format. I didn't realize that this differed when writing the logic to convert to routes.

The fix converts patterns using sourceToRegex() from routing-utils when returning routes format.

Note

Low Risk Change

This PR fixes a bug in route pattern conversion by properly transforming path-to-regexp patterns to regex format, which is a correctness fix for routing behavior rather than a security-sensitive change.

  • Adds sourceToRegex() conversion for route source patterns in rewrite/redirect logic
  • New convertDestination() helper replaces named params with capture group references
  • Test expectations updated to reflect proper regex output format

Risk assessment for commit 312e2c8.

@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Feb 19, 2026

🦋 Changeset detected

Latest commit: 312e2c8

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@vercel/config Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Feb 19, 2026

📦 CLI Tarball Ready

The Vercel CLI tarball for this PR is now available!

Quick Test

You can test this PR's CLI directly by running:

npx https://vercel-bi4kpd4w5.vercel.sh/tarballs/vercel.tgz --help

Use in vercel.json

To use this CLI version in your project builds, add to your vercel.json:

{
  "build": {
    "env": {
      "VERCEL_CLI_VERSION": "vercel@https://vercel-bi4kpd4w5.vercel.sh/tarballs/vercel.tgz"
    }
  }
}

Python Runtime Wheel

A Python runtime wheel was also built for this PR.
To use in your Python project builds, also set this environment variable:

VERCEL_RUNTIME_PYTHON="vercel-runtime @ https://vercel-bi4kpd4w5.vercel.sh/tarballs/vercel_runtime-0.5.0.dev1771466034+312e2c8-py3-none-any.whl"

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Feb 19, 2026

🧪 Unit Test Strategy

Comparing: 2cfc724312e2c8 (view diff)

Strategy: Code changed outside of a package - running all unit tests

⚠️ All unit tests will run because global code changes could impact all packages.

Affected packages - 16 (40%)
  1. @vercel/config
  2. @vercel/build-utils
  3. @vercel/client
  4. @vercel/firewall
  5. @vercel/fs-detectors
  6. @vercel/go
  7. @vercel/hydrogen
  8. @vercel/next
  9. @vercel/node
  10. @vercel/python
  11. @vercel/remix-builder
  12. @vercel/ruby
  13. @vercel/rust
  14. @vercel/static-build
  15. examples
  16. vercel
Unaffected packages - 24 (60%)
  1. @vercel-internals/get-package-json
  2. @vercel/backends
  3. @vercel/cervel
  4. @vercel/cli-auth
  5. @vercel/detect-agent
  6. @vercel/edge
  7. @vercel/elysia
  8. @vercel/error-utils
  9. @vercel/express
  10. @vercel/fastify
  11. @vercel/frameworks
  12. @vercel/functions
  13. @vercel/gatsby-plugin-vercel-builder
  14. @vercel/h3
  15. @vercel/hono
  16. @vercel/koa
  17. @vercel/nestjs
  18. @vercel/oidc
  19. @vercel/oidc-aws-credentials-provider
  20. @vercel/python-analysis
  21. @vercel/redwood
  22. @vercel/related-projects
  23. @vercel/routing-utils
  24. @vercel/static-config

Results

  • Unit tests: All affected packages will run unit tests
  • E2E tests: Running in parallel via E2E Tests workflow
  • Type checks: All affected packages will run type checks

This comment is automatically generated based on the affected testing strategy

@MatthewStanciu MatthewStanciu marked this pull request as ready for review February 19, 2026 01:54
@MatthewStanciu MatthewStanciu requested a review from a team as a code owner February 19, 2026 01:54
@MatthewStanciu MatthewStanciu merged commit 50f1d5d into main Feb 19, 2026
196 checks passed
@MatthewStanciu MatthewStanciu deleted the matthew/convert-routes-regexp branch February 19, 2026 19:17
ctgowrie pushed a commit that referenced this pull request Feb 19, 2026
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and publish to npm
yourself or [setup this action to publish
automatically](https://github.com/changesets/action#with-publishing). If
you're not ready to do a release yet, that's fine, whenever you add more
changesets to main, this PR will be updated.


# Releases
## vercel@50.21.0

### Minor Changes

- Add `--all` flag to `vercel ls` command and improve behavior when not
linked to a project
([#15143](#15143))

- `vercel ls` no longer requires a linked project. When not linked, it
now lists all deployments across all projects in the current scope
- Added `--all` flag to explicitly list deployments across all projects,
even when linked to a specific project
- Added "Project" column to the deployment table output to show which
project each deployment belongs to
- JSON output (`--format json`) is unchanged and continues to include
the `name` field for project name

### Patch Changes

- fix(cli): Handle SIGINT during upgrade prompt without showing a
stacktrace ([#15105](#15105))

- Use formatted tables for `metrics schema` output, matching the
convention used by other list commands
([#15138](#15138))

- Updated dependencies
\[[`5d1f55af04d0fdba7e7ac86f9eeda44316f54f5b`](5d1f55a)]:
    -   @vercel/next@4.15.31

## @vercel/config@0.0.33

### Patch Changes

- Fix rewrite regexp conversion when header transforms are present
([#15134](#15134))

## @vercel/next@4.15.31

### Patch Changes

- Added support for `regions` and `functionFailoverRegions` in
per-function configuration from `vercel.json` for Next.js projects.
([#15149](#15149))

## @vercel/python-runtime@0.4.3

### Patch Changes

- fix formatting and lint
([#15142](#15142))


<!-- VADE_RISK_START -->
> [!NOTE]
> Low Risk Change
>
> This PR is an automated Changesets release that only bumps version
numbers in package.json files, updates CHANGELOG.md files, and deletes
changeset markdown files - no code logic changes.
> 
> - Version bumps in package.json files (vercel, @vercel/config,
@vercel/next, @vercel/python-runtime)
> - CHANGELOG.md updates documenting previous changes
> - Deleted .changeset/*.md files consumed by release process
>
> <sup>Risk assessment for [commit
3b54c69](https://github.com/vercel/vercel/commit/3b54c6956719db3f1dfd50629330f42ab8143af6).</sup>
<!-- VADE_RISK_END -->

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
mitul-s pushed a commit that referenced this pull request Feb 22, 2026
The previous fix (#15134) only addressed pattern conversion when
rewrite() and redirect() methods returned Route objects with
transforms or env vars. This fix extends the conversion to the
getConfig() method, which converts redirects, rewrites, and headers
to routes format when routes are present.

Without this fix, patterns like `:path*` would be passed through
literally instead of being converted to proper regex, causing 404
errors.

https://claude.ai/code/session_01CeTsDHjUb1wrKjMEBCsv87
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants