{"record":{"id":"e96f4468d5256f85","repo":"TanStack/query","slug":"no-queryclient-found","errorCode":null,"errorMessage":"No QueryClient found","messagePattern":"No QueryClient found","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/angular-query-experimental/src/devtools-panel/inject-devtools-panel.ts","lineNumber":69,"sourceCode":"    }\n\n    if (!isBrowser)\n      return {\n        destroy,\n      }\n\n    effect(() => {\n      const {\n        client = injectedClient,\n        errorTypes = [],\n        styleNonce,\n        shadowDOMTarget,\n        onClose,\n        hostElement,\n      } = queryOptions()\n\n      untracked(() => {\n        if (!client) throw new Error('No QueryClient found')\n        if (!devtools && hostElement) {\n          import('@tanstack/query-devtools')\n            .then((queryDevtools) => {\n              devtools = new queryDevtools.TanstackQueryDevtoolsPanel({\n                client,\n                queryFlavor: 'Angular Query',\n                version: '5',\n                buttonPosition: 'bottom-left',\n                position: 'bottom',\n                initialIsOpen: true,\n                errorTypes,\n                styleNonce,\n                shadowDOMTarget,\n                onClose,\n                onlineManager,\n              })\n              devtools.mount(hostElement.nativeElement)\n            })","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/TanStack/query/blob/159982c80b844487054155c38ffc760fe4208daf/packages/angular-query-experimental/src/devtools-panel/inject-devtools-panel.ts#L51-L87","documentation":"Thrown by Angular's `injectDevtoolsPanel` inside its render effect when neither `devtoolsOptions().client` nor the Angular-DI-injected `QueryClient` is present. The devtools panel needs a live `QueryClient` instance to wire up `TanstackQueryDevtoolsPanel`, so it refuses to mount without one. It runs inside `untracked`, so the error propagates as an uncaught effect error during change detection.","triggerScenarios":"Calling `injectDevtoolsPanel(...)` in a component that is not under a tree where `provideTanStackQuery(new QueryClient(), ...)` (or an explicit `QueryClient` provider) is registered, AND the options callback does not pass `client: myClient`. Also occurs when the panel options function returns no `client` and the `inject(QueryClient, { optional: true })` at line 43 resolves to `null`.","commonSituations":"Forgetting `provideTanStackQuery` in `appConfig.providers`; lazy-loading a standalone component into an injector that lacks the `QueryClient` provider; providing the client only in a child injector while `injectDevtoolsPanel` runs in a parent; SSR where DI wiring differs; providing the client after the panel effect already ran.","solutions":["Register the QueryClient via `provideTanStackQuery(new QueryClient(), withDevtools(...))` (or `provideQueryClient(new QueryClient())`) in the same injector that hosts the component calling `injectDevtoolsPanel`.","Pass the client explicitly in the options callback: `injectDevtoolsPanel(() => ({ client: myClient, hostElement: ref, ... }))`.","Verify with the Angular devtools that the `QueryClient` token resolves at the component's injector by injecting it (optional) and logging before invoking the panel.","If using a standalone component loaded through `loadComponent`, ensure the route or shell `ApplicationConfig.providers` includes the QueryClient provider."],"exampleFix":"// before\nproviders: [provideRouter(routes)]\n// after\nproviders: [provideTanStackQuery(new QueryClient()), provideRouter(routes)]","handlingStrategy":"validation","validationCode":"// Before mounting the panel, ensure a client resolves.\nimport { inject, Injector } from '@angular/core'\nimport { QueryClient } from '@tanstack/query-core'\n\nfunction assertQueryClientAvailable(injector: Injector): QueryClient {\n  const client = injector.get(QueryClient, null)\n  if (!client) {\n    throw new Error('injectDevtoolsPanel: provide a QueryClient via provideTanStackQuery or pass client in options.')\n  }\n  return client\n}","typeGuard":"import { QueryClient } from '@tanstack/query-core'\nconst isQueryClient = (v: unknown): v is QueryClient =>\n  !!v && typeof (v as QueryClient).getQueryCache === 'function' && typeof (v as QueryClient).defaultQueryOptions === 'function'","tryCatchPattern":"// Wrap the effect body so a missing client logs instead of crashing change detection.\ntry {\n  if (!client) throw new Error('No QueryClient found')\n  // ...mount devtools\n} catch (err) {\n  console.error('[devtools-panel] skipped:', (err as Error).message)\n}","preventionTips":["Always pair `withDevtools`/`injectDevtoolsPanel` with `provideTanStackQuery(new QueryClient(), ...)`.","In tests, provide a stub QueryClient in the testing module config.","For lazy-loaded components, ensure the route providers include the QueryClient.","Pass the client explicitly in the options callback as a safety net."],"tags":["angular","devtools","dependency-injection","queryclient","configuration"],"backgroundTag":null,"analyzedSha":"159982c80b844487054155c38ffc760fe4208daf","analyzedAt":"2026-08-12T16:21:52.822Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}