TanStack/query · error

usePiPWindow must be used within a PiPProvider

Error message

usePiPWindow must be used within a PiPProvider

What it means

Thrown by `usePiPWindow()` (the devtools PiP context hook) when `useContext(PiPContext)` returns `undefined`, meaning the hook was called outside a `<PiPProvider>`. This is the standard Solid context-missing-consumer guard: the hook needs the PiP signal/value that only the provider creates, and without it the consumer would dereference `undefined` immediately, so it throws early with an actionable message.

Source

Thrown at packages/query-devtools/src/contexts/PiPContext.tsx:199

  })

  const value = createMemo(() => ({
    pipWindow: pipWindow(),
    requestPipWindow,
    closePipWindow,
    disabled: props.disabled ?? false,
  }))

  return (
    <PiPContext.Provider value={value}>{props.children}</PiPContext.Provider>
  )
}

export const usePiPWindow = () => {
  const context = createMemo(() => {
    const ctx = useContext(PiPContext)
    if (!ctx) {
      throw new Error('usePiPWindow must be used within a PiPProvider')
    }
    return ctx()
  })
  return context
}

View on GitHub (pinned to 159982c80b)

Solutions

  1. Ensure the component calling `usePiPWindow()` is rendered inside `<PiPProvider>` (in the devtools, this is wired by the devtools tree itself — do not import this hook into app code).
  2. If writing a test, wrap the rendered component in `<PiPProvider localStore={...} setLocalStore={...}>...</PiPProvider>`.
  3. Deduplicate the devtools package — check `pnpm why @tanstack/query-devtools` / `npm ls` and align versions so the context singleton is shared.
  4. Do not use `usePiPWindow` in application code; it is an internal hook. Use the public `<ReactQueryDevtools />` component instead.

Example fix

// before - hook used outside provider
const ctx = usePiPWindow()
return <Panel />

// after - wrap with PiPProvider (internal devtools usage)
<PiPProvider localStore={store} setLocalStore={setStore}>
  <Panel />
</PiPProvider>
Defensive patterns

Strategy: type-guard

Validate before calling

// Verify context is present before calling the hook's body
import { useContext } from 'solid-js'
import { PiPContext } from '@tanstack/query-devtools'
const isInsidePiPProvider = () => useContext(PiPContext) !== undefined

Type guard

// Narrow before relying on the context value
import { useContext } from 'solid-js'
import { PiPContext } from '@tanstack/query-devtools'
const hasPiPContext = (): boolean => useContext(PiPContext) !== undefined

Try / catch

let ctx
try {
  ctx = usePiPWindow()
} catch (e) {
  if (e.message === 'usePiPWindow must be used within a PiPProvider') {
    // render without PiP, or wrap the tree in <PiPProvider> upstream
    return null
  }
  throw e
}

Prevention

When it happens

Trigger: Calling `usePiPWindow()` in a component that is rendered outside the `<PiPProvider>` subtree; importing `usePiPWindow` and using it in app code (it is an internal devtools hook); rendering a PiP-consuming component in a test without wrapping it in `PiPProvider`; module duplication where the `PiPContext` singleton differs between two copies of the devtools package.

Common situations: Internal devtools component accidentally imported into app code; tests rendering a devtools subcomponent in isolation without the provider tree; npm/pnpm hoisting causing two installations of `@tanstack/query-devtools` so the context object identity differs between provider and consumer; SSR rendering where the provider was conditionally skipped.

Related errors


AI-assisted analysis of TanStack/query@159982c80b (2026-08-12). Data as JSON: /api/errors/243c3a1fbd8e05a8. Report an issue: GitHub.