Skip to content

Search middleware changes objects unexpectedly #6298

@benjavicente

Description

@benjavicente

Which project does this relate to?

Router Core, search middlewares: https://github.com/TanStack/router/blob/main/packages/router-core/src/searchMiddleware.ts

Describe the bug

The search middleware changes the search object. This can cause unexpected behavior when the search object is the same across multiple runs of a Link component.

This does not affect the use case where the search options are provided directly in the Link in React and Solid.

Your Example Website or App

https://github.com/benjavicente/router-mutable-search-repo

Steps to Reproduce the Bug or Issue

  1. Add retainSearchParams(["exampleRetainedSearchParam"]) to a parent root (for example, __root.tsx)
  2. Create a search object in a route (for example, index.tsx) and keep the reference. It can be a global variable, or a variable that lives in the lifecycle of the component.
    const searchRef = useRef({ id: "1" as const });
  3. Add that to a link
    <Link to="/post" search={searchRef.current}>
  4. Change the search parameters to include "exampleRetainedSearchParam". Update it multiple times.
  5. Log the search reference. The bug is that it now has exampleRetainedSearchParam with the value added to it on its first run.

This can break the page in some cases when that search param was not expected, and it breaks retainSearchParams itself.

See the example repo above for a full example.

Expected behavior

It should not mutate the search parameters object provided to the router.

Screenshots or Videos

Screen.Recording.2026-01-04.at.17.22.45.mov

Platform

  • Router / Start Version: 1.132.0

Additional context

I think having the same reference would be rare for React and Solid, where the props can get a different object each time, but other adapters with different prop behaviors might break with this.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions