fix: add depth limit and cycle detection to convertBigIntToString #250
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Description
Summary:
convertBigIntToStringinpackages/react-router-devtools/src/shared/bigint-util.tsrecurses over loader/route data with no depth limit or cycle detection. When loader data is very deep (e.g. TanStack QuerydehydratedStatewith many pages of posts) or contains circular references, the function blows the call stack and the devtools crash with "RangeError: Maximum call stack size exceeded" in the RouteSegmentInfo component.This change adds an optional max depth (and cycle detection via a
WeakSet) so that deep or cyclic structures are truncated with placeholders instead of causing infinite recursion. The serialized output for display remains bounded and the devtools no longer crash on routes that return heavy loader data.Motivation: Routes that return
dehydrate(queryClient)and/or Promises (e.g. pages with prefetched infinite queries) were causing the devtools to crash when opening the Routes tab. The fix keeps the existing behavior for normal payloads and only limits recursion for problematic ones.Dependencies: None. Change is confined to
shared/bigint-util.ts(and call sites if you added an options argument).Type of change
How Has This Been Tested?
dehydratedStatewith a large infinite-query cache and/or circular references."[Max depth reached]"/"[Circular]").Repro (before fix): Use a loader that returns
dehydrate(queryClient)including a heavy infinite query. Open that route with React Router devtools visible; the RouteSegmentInfo component crashes with "Maximum call stack size exceeded".bigint-util.ts, add a test that deep/cyclic input is truncated and does not throw)Checklist: