\n\n### Link to reproduction\n\nhttps://trpc.io/\n\n### To reproduce\n\nGo to https://trpc.io/, select the react option under 'Try it out for yourself', emamine the types in Greeting.tsx\n\n### Additional information\n\n_No response_\n\n### 👨👧👦 Contributing\n\n- [ ] 🙋♂️ Yes, I'd be down to file a PR fixing this bug!",[3020,3023],{"name":3021,"color":3022},"blocked","111111",{"name":3024,"color":3025},"🐛 bug: unconfirmed","e99695",6521,"trpc","open","bug: Type error in homepage demo of new tanstack query client","2025-03-12T13:50:30Z","https://github.com/trpc/trpc/issues/6521",0.7462143,{"description":3034,"labels":3035,"number":3042,"owner":3027,"repository":3027,"state":3028,"title":3043,"updated_at":3044,"url":3045,"score":3046},"### Describe the feature you'd like to request\r\n\r\nI think the fetch's design is better in terms of error handling, since typescript cannot type errors. So catching an error is not type-safe.\r\n\r\n> It returns a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that resolves to the [Response](https://developer.mozilla.org/en-US/docs/Web/API/Response) to that request — as soon as the server responds with headers — **even if the server response is an HTTP error status.** - https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API\r\n\r\nIf I send a 400 status code because the email is already set on a registration page, I cannot easily propagate the error back to the email input field, because tRPC can only type the 200 status.\r\n\r\nI built a similar setup to tRPC before I found it, and I think I handled the errors better. In my case the return type was a [discriminated union](https://www.typescriptlang.org/docs/handbook/unions-and-intersections.html#discriminating-unions) of every possible response that the backend can send, including Internal Server Error, if the client wanted to handle that case.\r\n\r\nI think it is an anti-pattern to use nature js errors in typescript. Sometimes throwing is useful, but it's not a safe thing to do. And I would like safety.\r\n\r\nIn my case, I defined the controllers like this:\r\n```ts\r\nexport const authByAuthenticator = withResponse(async (req) => {\r\n const data = AuthByAuthenticator.schema.parse(req.body)\r\n const authResult = await authenticatorAuthService.authByAuthenticator(\r\n req.user.email,\r\n data.token\r\n )\r\n switch (authResult.result) {\r\n case 'accessDenied':\r\n return unauthorizedError()\r\n case 'wrongTOTP':\r\n return zodValidationError([\r\n {\r\n code: 'custom',\r\n path: ['token'],\r\n message: 'Wrong OTP'\r\n }\r\n ])\r\n case 'success':\r\n await authOTPLimit.resolve(req)\r\n return success({\r\n token: authResult.token,\r\n message: 'Good OTP, redirecting...'\r\n })\r\n }\r\n})\r\n```\r\n\r\n\r\n### Describe the solution you'd like to see\r\n\r\nI would like to have a way to return something like this:\r\n\r\n```ts\r\nif(somethingElse)\r\n return {\r\n statusCode: 400,\r\n result: 'somethingElse' as const,\r\n somethingElseThatExistsOnlyThisCase: 123\r\n // ...\r\n }\r\n \r\nreturn {\r\n statusCode: 200,\r\n result: 'success' as const,\r\n somethingThatExistsOnlyThisCase: 42\r\n // ...\r\n}\r\n``` \r\n\r\nAnd I would like to get this back clientside, as well when the status is not 200\r\n```ts\r\nif(response.result === 'success') {\r\n console.log(response.somethingThatExistsOnlyThisCase)\r\n} else if(response.result === 'somethingElse') {\r\n // Do something else and typesafely access special fields\r\n console.log(response.somethingElseThatExistsOnlyThisCase)\r\n}\r\n```\r\n\r\n### Describe alternate solutions\r\n\r\nI can achieve the same thing if I use 200 for every request, but it's not the same.\r\n\r\n### Additional information\r\n\r\n_No response_\r\n\r\n### 👨👧👦 Contributing\r\n\r\n- [X] 🙋♂️ Yes, I'd be down to file a PR implementing this feature!\n\n\u003Csub>[TRP-37](https://linear.app/trpc/issue/TRP-37/feat-fetch-like-behaviour-for-non-200-error-codes)\u003C/sub>",[3036,3039],{"name":3037,"color":3038},"💡 ideas","bfdadc",{"name":3040,"color":3041},"next-major/maybe","D4C5F9",3438,"feat: inferable errors from procedures","2025-03-20T15:41:30Z","https://github.com/trpc/trpc/issues/3438",0.7593918,{"description":3048,"labels":3049,"number":3053,"owner":3027,"repository":3027,"state":3054,"title":3055,"updated_at":3056,"url":3057,"score":3058},"I have a procedure that doesn't expect an input, if I use the `httpBatchLink` I can call it without any issue, however if I try using the `httpLink`, the server fails with a `BAD_REQUEST` and complains that an input has been provided. Did a little digging and it appears that in that case the client sends a `{}` instead of `null`.",[3050],{"name":3051,"color":3052},"🔎 needs more investigation/info","d4c5f9",1462,"closed","Inconsistent behavior between httpLink and httpBatchLink","2022-10-04T12:03:37Z","https://github.com/trpc/trpc/issues/1462",0.73368675,{"description":3060,"labels":3061,"number":3062,"owner":3027,"repository":3027,"state":3054,"title":3063,"updated_at":3064,"url":3065,"score":3066},"### Provide environment information\r\n\r\n```\r\n System:\r\n OS: macOS 13.1\r\n CPU: (10) arm64 Apple M1 Max\r\n Memory: 867.38 MB / 32.00 GB\r\n Shell: 5.8.1 - /bin/zsh\r\n Binaries:\r\n Node: 16.14.2 - ~/Library/Caches/fnm_multishells/76195_1680926422917/bin/node\r\n Yarn: 1.22.19 - /opt/homebrew/bin/yarn\r\n npm: 8.5.0 - ~/Library/Caches/fnm_multishells/76195_1680926422917/bin/npm\r\n Browsers:\r\n Chrome: 111.0.5563.146\r\n Firefox: 111.0.1\r\n Safari: 16.2\r\n npmPackages:\r\n @tanstack/react-query: ^4.28.0 => 4.28.0 \r\n @trpc/client: ^10.19.1 => 10.19.1 \r\n @trpc/next: ^10.19.1 => 10.19.1 \r\n @trpc/react-query: ^10.19.1 => 10.19.1 \r\n @trpc/server: ^10.19.1 => 10.19.1 \r\n next: ^13.3.0 => 13.3.0 \r\n react: ^18.2.0 => 18.2.0 \r\n typescript: ^5.0.4 => 5.0.4 \r\n```\r\n\r\n### Describe the bug\r\n\r\nI'm encountering an infinite fetching/rendering loop under these circumstances: \r\n\r\n**Server Side**\r\nA query router that throws an error or TRPCError. For example:\r\n```typescript\r\n greeting: publicProcedure\r\n .input(z.object({ name: z.string() }))\r\n .query(({ input }) => {\r\n throw new Error(\"TEST ERR\");\r\n return {\r\n text: `hello ${input?.name ?? \"world\"}`,\r\n };\r\n }),\r\n```\r\n\r\n\r\n**Client Side**\r\nA `trpc.greeting.useQuery()` hook in a main react component\r\n```typescript\r\n// Greeting.tsx\r\n const greeting = trpc.greeting.useQuery(\r\n { name: \"tRPC user\" },\r\n { retry: false }\r\n );\r\n\r\n```\r\n An identical `trpc.greeting.useQuery()` hook (same query key) in a nested react component\r\n```typescript\r\n// /components/NestedComponent.tsx\r\n const greeting = trpc.greeting.useQuery(\r\n { name: \"tRPC user\" },\r\n { retry: false }\r\n );\r\n\r\n```\r\n\r\nAn imported NestedComponent in the main component but with an early return based off of greeting.isLoading:\r\n```typescript\r\n// Greeting.tsx\r\n\r\nimport { NestedComponent } from \"./components/NestedComponent\";\r\nimport { trpc } from \"./utils/trpc\";\r\n\r\nexport function Greeting() {\r\n const greeting = trpc.greeting.useQuery(\r\n { name: \"tRPC user\" },\r\n { retry: false }\r\n );\r\n\r\n if (greeting.isLoading) {\r\n return \u003C>Render Count... {renderCount}\u003C/>;\r\n }\r\n\r\n return (\r\n \u003Cdiv>\r\n \u003CNestedComponent />\r\n {greeting.data?.text}\r\n \u003C/div>\r\n );\r\n}\r\n```\r\n\r\nThese combinations of items will cause an infinite fetching/render loop for trpc.greeting.useQuery() even with retry set to false.\r\n\r\n**Expected behavior**\r\nI would expect that the early return boolean would flip eventually and would allow the main function to render properly after it tries one time to fetch the query (retry=false)\r\n\r\n\r\n\r\n\r\n### Link to reproduction\r\n\r\n\r\n[https://codesandbox.io/p/github/mcunningham/trpc-infinite-loop/main](https://codesandbox.io/p/github/mcunningham/trpc-infinite-loop/main?file=README.md&workspace=%257B%2522activeFilepath%2522%253A%2522README.md%2522%252C%2522openFiles%2522%253A%255B%2522README.md%2522%252C%2522%252Fclient%252Fsrc%252Fcomponents%252FNestedComponent.tsx%2522%252C%2522%252Fclient%252Fsrc%252FGreeting.tsx%2522%255D%252C%2522sidebarPanel%2522%253A%2522EXPLORER%2522%252C%2522gitSidebarPanel%2522%253A%2522COMMIT%2522%252C%2522spaces%2522%253A%257B%2522clg7iqcux000x3b6k3wb2s46e%2522%253A%257B%2522key%2522%253A%2522clg7iqcux000x3b6k3wb2s46e%2522%252C%2522name%2522%253A%2522Default%2522%252C%2522devtools%2522%253A%255B%257B%2522key%2522%253A%2522clg7kvr2u00153b6kutbekix9%2522%252C%2522type%2522%253A%2522PROJECT_SETUP%2522%252C%2522isMinimized%2522%253Afalse%257D%252C%257B%2522type%2522%253A%2522PREVIEW%2522%252C%2522taskId%2522%253A%2522dev%2522%252C%2522port%2522%253A3000%252C%2522key%2522%253A%2522clg7iqr13009l3b6k1yn408rz%2522%252C%2522isMinimized%2522%253Afalse%257D%252C%257B%2522type%2522%253A%2522TASK_LOG%2522%252C%2522taskId%2522%253A%2522dev%2522%252C%2522key%2522%253A%2522clg7iqojr004f3b6kfjn95hky%2522%252C%2522isMinimized%2522%253Afalse%257D%255D%257D%257D%252C%2522currentSpace%2522%253A%2522clg7iqcux000x3b6k3wb2s46e%2522%252C%2522spacesOrder%2522%253A%255B%2522clg7iqcux000x3b6k3wb2s46e%2522%255D%252C%2522hideCodeEditor%2522%253Afalse%257D)\r\n\r\n### To reproduce\r\n\r\n\r\nThe reproduction [codesandbox link](https://codesandbox.io/p/github/mcunningham/trpc-infinite-loop/main?file=README.md&workspace=%257B%2522activeFilepath%2522%253A%2522README.md%2522%252C%2522openFiles%2522%253A%255B%2522README.md%2522%252C%2522%252Fclient%252Fsrc%252Fcomponents%252FNestedComponent.tsx%2522%252C%2522%252Fclient%252Fsrc%252FGreeting.tsx%2522%255D%252C%2522sidebarPanel%2522%253A%2522EXPLORER%2522%252C%2522gitSidebarPanel%2522%253A%2522COMMIT%2522%252C%2522spaces%2522%253A%257B%2522clg7iqcux000x3b6k3wb2s46e%2522%253A%257B%2522key%2522%253A%2522clg7iqcux000x3b6k3wb2s46e%2522%252C%2522name%2522%253A%2522Default%2522%252C%2522devtools%2522%253A%255B%257B%2522key%2522%253A%2522clg7kvr2u00153b6kutbekix9%2522%252C%2522type%2522%253A%2522PROJECT_SETUP%2522%252C%2522isMinimized%2522%253Afalse%257D%252C%257B%2522type%2522%253A%2522PREVIEW%2522%252C%2522taskId%2522%253A%2522dev%2522%252C%2522port%2522%253A3000%252C%2522key%2522%253A%2522clg7iqr13009l3b6k1yn408rz%2522%252C%2522isMinimized%2522%253Afalse%257D%252C%257B%2522type%2522%253A%2522TASK_LOG%2522%252C%2522taskId%2522%253A%2522dev%2522%252C%2522key%2522%253A%2522clg7iqojr004f3b6kfjn95hky%2522%252C%2522isMinimized%2522%253Afalse%257D%255D%257D%257D%252C%2522currentSpace%2522%253A%2522clg7iqcux000x3b6k3wb2s46e%2522%252C%2522spacesOrder%2522%253A%255B%2522clg7iqcux000x3b6k3wb2s46e%2522%255D%252C%2522hideCodeEditor%2522%253Afalse%257D) shows an example using a slightly modified [minimal-react ](https://github.com/trpc/trpc/tree/main/examples/minimal-react) example. It shows an infinite loop state with a nested component imported into a main component returning early with the mock error being thrown immediately in the server side route. I have also been able to reproduce this in nextjs as well.\r\n\r\n\r\n\r\n### Additional information\r\n\r\n_No response_\r\n\r\n### 👨👧👦 Contributing\r\n\r\n- [ ] 🙋♂️ Yes, I'd be down to file a PR fixing this bug!",[],4158,"bug: Infinite loop with main component + nested component calling identical .useQuery() hooks","2023-04-22T12:02:12Z","https://github.com/trpc/trpc/issues/4158",0.73856044,{"description":3068,"labels":3069,"number":3070,"owner":3027,"repository":3027,"state":3054,"title":3071,"updated_at":3072,"url":3073,"score":3074},"",[],1066,"❤️ ","2022-10-04T18:08:10Z","https://github.com/trpc/trpc/issues/1066",0.73946893,{"description":3076,"labels":3077,"number":3081,"owner":3027,"repository":3027,"state":3054,"title":3082,"updated_at":3083,"url":3084,"score":3085},"### Describe the feature you'd like to request\r\n\r\nSince trpc wraps react-query, add the option for trpc to debounce and throttle any changes to the input of queries. To avoid having a wrapper (debounce) of a wrapper (trpc) of a wrapper (react-query) of a wrapper (fetch).\r\n\r\n### Describe the solution you'd like to see\r\n\r\n``` typescript\r\nconst [search, setsearch] = useState(\"\")\r\nconst { data } = api.category.index.useQuery({\r\n search,\r\n // other params such as pagination\r\n}, {\r\n throttle: 500,\r\n})\r\n```\r\n\r\n### Describe alternate solutions\r\n\r\nCurrently I have to add an helper function to delay propagation of the state to the useQuery method. This is not ideal since it can't be properly wrapped and add an additional step layer to any implementation required.\r\n\r\n### Additional information\r\n\r\n_No response_\r\n\r\n### 👨👧👦 Contributing\r\n\r\n- [X] 🙋♂️ Yes, I'd be down to file a PR implementing this feature!",[3078],{"name":3079,"color":3080},"wontfix","ffffff",3972,"feat: throttle and debounce","2023-03-25T18:01:42Z","https://github.com/trpc/trpc/issues/3972",0.7486981,{"description":3087,"labels":3088,"number":3092,"owner":3027,"repository":3027,"state":3054,"title":3093,"updated_at":3094,"url":3095,"score":3096},"### Area of Improvement\n\nNot sure whether it's an error solely from my repo.\r\n\r\nIn order to integrate with existing react-query, I needed to make a new `QueryClientProvider` with context. If there is no context, the trpc react-query will throw `No QueryClient Set ....`. If there is only one `QueryClientProvider` with context, the existing react-query will throw `No QueryClient Set ....`.\r\n\r\nThe following code solves my issue.\r\n\r\ntrpc.ts\r\n```javascript\r\nexport const context = createContext\u003CQueryClient | undefined>(undefined);\r\n\r\nexport const trpc = createTRPCReact\u003CAppRouter>({ reactQueryContext: context });\r\n```\r\n\r\nApp.tsx\r\n```diff\r\n+ \u003Ctrpc.Provider client={trpcClient} queryClient={queryClient}>\r\n+ \u003CQueryClientProvider client={queryClient} context={context}>\r\n \u003CQueryClientProvider client={queryClient}>\r\n ...app\r\n \u003C/QueryClientProvider>\r\n+ \u003C/QueryClientProvider>\r\n+ \u003C/trpc.Provider>\r\n```\r\n\r\nRelated:\r\n[react-query v4 docs](https://tanstack.com/query/v4/docs/react/guides/migrating-to-react-query-4#custom-contexts-for-multiple-providers)\r\n[another issue](https://github.com/trpc/trpc/issues/3316)\n\n### Link to related docs\n\n_No response_\n\n### Additional information\n\n_No response_\n\n### 👨👧👦 Contributing\n\n- [x] 🙋♂️ Yes, I'd be down to file a PR implementing the suggested changes!",[3089],{"name":3090,"color":3091},"📚 documentation / examples","0075ca",3987,"docs: trpc with existed react-query","2023-03-14T13:03:02Z","https://github.com/trpc/trpc/issues/3987",0.75174594,{"description":3098,"labels":3099,"number":3100,"owner":3027,"repository":3027,"state":3054,"title":3101,"updated_at":3044,"url":3102,"score":3103},"I had a new idea yesterday that would be amazing if implemented. \r\n\r\n\r\n## Problem\r\n\r\nWhen using tRPC, it's easy to accidentally leak sensitive information since you don't have output validation like in GraphQL.\n\nIt's also hard to track if you're doing accidental breaking changes to your API for clients that are running right now or can't be upgraded easily (e.g. React Native) \r\n\r\n## Implementation idea\r\n\r\nOutputs could have a `trpc.snapshot()` similar to Jest snapshots. We would need to have a CLI that runs in your development, analyzes the typescript & updates the snapshots for you. \r\n\r\nThis would remove the whole burden of writing output schema (could reset with `trpc -u` ) whilst still guaranteeing an output that can be reviewed in PRs easily.\r\n\r\n### tRPC CLI commands\r\n\r\n```sh\r\n-w, --watch Start watcher\r\n-u, --update-snapshots Update all snapshots\r\n```\r\n\r\n\r\n### Example\r\n\r\n#### Input\r\n```ts\r\nconst procedure = trpc.procedure\r\n .output(\r\n trpc.snapshot()\r\n )\r\n .resolve(() => ({ foo: 'bar' })\r\n\r\n```\r\n#### Output\r\n\r\nIt could generate a zod parser or something.\r\n\r\n```ts\r\nconst procedure = trpc.procedure\r\n .output(\r\n trpc.snapshot(\r\n /* \u003C✨ Auto-generated ✨ > */\r\n z.object({ foo: z.string() })\r\n /* \u003C/✨ > */\r\n )\r\n )\r\n .resolve(() => ({ foo: 'bar' })\r\n```\r\n\r\n#### Rough outline of how it'd work\r\n\r\n\r\n1. Convert the typescript in your app to an AST (abstract syntax tree)\r\n1. Find the `snapshot()` calls \r\n 1. If empty, convert the the inferred output into a validator (like zod)\r\n 2. If non-empty\r\n 1. If running with `--update-snapshots`: \r\n 1. Clear value\r\n 2. Go to 2.1\r\n 1. Else ignore\r\n\r\nPotentially a `trpc.config.ts` would be good to specify watch folder, etc\r\n\r\n## Notes\r\n\r\n\r\n- Ideally, it would be a performant parser, see https://github.com/moltar/typescript-runtime-type-benchmarks\r\n- Did some quick googles for similar libraries:\r\n - https://github.com/harryparkdotio/ts-ast-serializer\r\n - Maybe it could be a lint package? https://npmmirror.com/package/@kvganesan/typescript-estree\n\n\u003Csub>[T-76](https://linear.app/trpc/issue/T-76/feat-trpcsnapshot)\u003C/sub>",[],3435,"feat: `trpc.snapshot()`","https://github.com/trpc/trpc/issues/3435",0.7584326,{"description":3105,"labels":3106,"number":3108,"owner":3027,"repository":3027,"state":3054,"title":3109,"updated_at":3110,"url":3111,"score":3112},"### Area of Improvement\r\n\r\nSeems like the Tanstack folks have changed around the URL structure of their documentation sites. There are 35 links in the codebase to `https://react-query.tanstack.com`, which all lead to the homepage of the v3 site. The current correct link is `https://tanstack.com/query/v4`.\r\n\r\nWe just need to go through and find the up to date link. Probably pretty easy to find and replace but it'd be good to check manually that the updated links are correct.\r\n\r\nNote - this is most impactful in documentation, where people are likely to click on them, but a lot of instances are in JSDoc comments. Both should probably be fixed.\r\n\r\n### Link to related docs\r\n\r\nhttps://trpc.io/docs/nextjs/server-side-helpers\r\n\r\n### Additional information\r\n\r\n_No response_\r\n\r\n### 👨👧👦 Contributing\r\n\r\n- [X] 🙋♂️ Yes, I'd be down to file a PR implementing the suggested changes!",[3107],{"name":3090,"color":3091},4165,"docs: Links to React Query documentation are dead","2023-04-24T18:02:00Z","https://github.com/trpc/trpc/issues/4165",0.7591663,{"description":3114,"labels":3115,"number":3120,"owner":3027,"repository":3027,"state":3054,"title":3121,"updated_at":3122,"url":3123,"score":3124},"Can we leverage [Docusaurus versioning](https://docusaurus.io/docs/versioning) for V10?\r\n\r\nI **don't** want to do versioning for each minor/major, but it would be nice to have a `9.x` and `10.x` checked in.\r\n\r\nOtherwise, it's also perfectly fine if we have to independently deployed apps as well.\r\n\r\n",[3116,3117],{"name":3040,"color":3041},{"name":3118,"color":3119},"🕸 www","666FF9",2179,"Can we leverage Docusaurus versioning?","2022-10-04T06:09:04Z","https://github.com/trpc/trpc/issues/2179",0.7596908,["Reactive",3126],{},["Set"],["ShallowReactive",3129],{"$fTRc1wZytZ_XrK4EfJfei_Sz-An4H4Yy6syhVxH_PVJc":-1,"$fcCjBgxuFdjKaLMifmVXrQ-gPAUPUqCEEVxKxEiDabEc":-1},"/trpc/trpc-openapi/420"]