From e0d94e8343c8b646f1901d46dcfb54748e549ec2 Mon Sep 17 00:00:00 2001 From: sktbrd Date: Sun, 16 Aug 2026 22:38:41 -0300 Subject: [PATCH] fix(providers): mount QueryClientProvider while the wagmi config loads Web3Providers creates the wagmi config in an effect, so `config` is null on the first client render and during SSR. That branch returned `stores` with no QueryClientProvider, so any component calling useQuery while it was live threw "No QueryClient set". This was reachable from ordinary pages, not just edge cases: ProposalTransactionList renders a Row per transaction, Row calls useDecodedTx, and useDecodedTx calls useQuery. Rendering that during SSR threw, so the error propagated to the route and /proposals/[id] returned a 500. /dev/proposal 500'd for the same reason via its decoded-tx taxonomy section. Verified against a dev server, same commit, fix stashed and unstashed: without the fix /proposals/1 500 /proposals/5 500 /dev/proposal 500 with the fix /proposals/1 200 /proposals/5 200 /dev/proposal 200 queryClient is a module-level singleton, so both branches share one cache and nothing is refetched when the config resolves and the tree swaps. Co-Authored-By: Claude Opus 5 (1M context) --- src/app/web3-providers.tsx | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/app/web3-providers.tsx b/src/app/web3-providers.tsx index 833f1f0c0..07641813d 100644 --- a/src/app/web3-providers.tsx +++ b/src/app/web3-providers.tsx @@ -67,8 +67,20 @@ export function Web3Providers({ children }: { children: React.ReactNode }) { ) + // `QueryClientProvider` has to wrap `stores` in BOTH branches. wagmi's config + // is created in the effect above, so on the first client render `config` is + // still null — and any component that calls `useQuery` while this branch is + // live throws "No QueryClient set". That is reachable from ordinary pages: + // `ProposalTransactionList` → `useDecodedTx` → `useQuery` renders during SSR, + // which took `/proposals/[id]` down with a 500. `queryClient` is a module + // singleton, so both branches share one cache and nothing is refetched when + // the config resolves and the tree swaps. if (!config) { - return {stores} + return ( + + {stores} + + ) } return (