router icon indicating copy to clipboard operation
router copied to clipboard

Numeric search parameters wrongly parsed and wrapped with quotes

Open isnifer opened this issue 2 weeks ago โ€ข 5 comments

Which project does this relate to?

Router

Describe the bug

The problem is that Router interprets Strings that look like a Number as Numbers at some point. This behavior introduces 2 major issues:

  1. Numeric strings wrapped with double quotes โ€” they shouldn't.
  2. If the numbers (that I expect to read as strings in my schema) are too large โ€” they are modified.

So when I will pass &numericString=723421968459640832 to URL it will be transformed twice:

  1. 723421968459640832 became 723421968459640800 (since it's too big for Number)
  2. And it will be wrapped with "" and became &numericString="723421968459640800"

And the code is here โ€” https://github.com/isnifer/tanstack-issue-537/blob/master/src/routes/issue.tsx

And yes I see your response here https://github.com/TanStack/router/discussions/989#discussioncomment-8125891 to transform big numbers to add double quotes, but c'mon, it should not be double quotes for numeric strings at all.

UPD: I've added a second page with the same Zod schema where I need to parse z.coerce.string() value from params โ€“ and it just works. No double quotes, no transformation URL => number => string. And added example with EXPECTED issue of casting from string to number (z.coerce.number()) to show the difference.

Your Example Website or App

https://tsr-issue-537.netlify.app

Steps to Reproduce the Bug or Issue

  1. Go to site
  2. Click to link on top
  3. Watch to search parameters in URL
  4. Read steps on that page

Expected behavior

As a user, I expected โ€” numeric parameters even expected as strings would NOT be wrapped with double quotes and would NOT parsed after page transition. Since HUGE numbers will change their values to unpredictable like 723421968459640832 became 723421968459640800 in the provided example.

Screenshots or Videos

I recorded an example and made it slow to 0.25x, you can see how the Router transforms the URL. You can find out on the 00:08 how it makes these 2 changes.

https://github.com/user-attachments/assets/55d990ae-a286-4ee4-aa57-34f90668d843

Platform

  • Router / Start Version: 1.132.0
  • OS: macOS
  • Browser: Chrome
  • Browser Version: 144.0.7559.4 beta (arm64)
  • Bundler: vite
  • Bundler Version: ^7.1.7

Additional context

No response

isnifer avatar Dec 08 '25 16:12 isnifer

๐Ÿ“ CodeRabbit Plan Mode

Generate an implementation plan and agent prompts for this issue.

  • [ ] Create Plan
Examples

๐Ÿ”— Related PRs

TanStack/router#5120 - fix(router-core): parse _strictParams. [merged] TanStack/router#5124 - fix(router-core): params.parse should run as minimally as possible [merged] TanStack/router#5624 - fix: fix transform id regex [merged] TanStack/router#5802 - test(router, start): query navigation transitions [merged] TanStack/router#5871 - fix: handle $&quot in defaultRenderHandler correctly [merged]

๐Ÿ‘ค Suggested Assignees

  • nlynzaad
  • schiller-manuel
  • birkskyum
  • Dubzer

๐Ÿงช Issue enrichment is currently in early access.

To disable automatic issue enrichment, add the following to your .coderabbit.yaml:

issue_enrichment:
  auto_enrich:
    enabled: false

coderabbitai[bot] avatar Dec 08 '25 16:12 coderabbitai[bot]

Here is a quick-fix if you need:

import { createRouter, parseSearchWith, stringifySearchWith } from '@tanstack/react-router';

function parseSearch(value: string) {
  const parsed = JSON.parse(value) as object;
  if (parsed && typeof parsed === 'object') {
    return parsed;
  }
  return value;
}

function stringifySearch(value: string) {
  const parsed = parseSearch(value);
  if (parsed && typeof parsed === 'object') {
    return JSON.stringify(value);
  }
  return value;
}

const router = createRouter({
  routeTree,
  basepath: '/',
  context: {},
  defaultPreload: 'intent',
  scrollRestoration: true,
  defaultStructuralSharing: true,
  defaultPreloadStaleTime: 0,
  parseSearch: parseSearchWith(parseSearch),
  stringifySearch: stringifySearchWith(stringifySearch, parseSearch),
});

adbjo avatar Dec 09 '25 14:12 adbjo

@adbjo Thank you. I think that this is an issue that requires a fix, not a workaround.

isnifer avatar Dec 09 '25 14:12 isnifer

@isnifer I put up a PR: https://github.com/TanStack/router/pull/6000 :)

adbjo avatar Dec 09 '25 14:12 adbjo

@isnifer The quick-fix didn't quite work, i updated it now

adbjo avatar Dec 09 '25 15:12 adbjo