vercel/next.js · error · Error
`${callingExpression}` was called outside a request scope. R
Error message
`${callingExpression}` was called outside a request scope. Read more: https://nextjs.org/docs/messages/next-dynamic-api-wrong-context What it means
throwForMissingRequestStore() is invoked by useDynamicSearchParams (and similar dynamic APIs) when workUnitAsyncStorage.getStore() returns undefined -- meaning the call happened outside any request/prerender scope. Dynamic APIs like useSearchParams, use(), cookies, headers, etc. require a request context to resolve; calling them in module scope, top-level code, or a non-request context throws this.
Source
Thrown at packages/next/src/server/app-render/work-unit-async-storage.external.ts:480
case 'prerender-ppr':
case 'prerender-legacy':
return true
case 'request':
case 'prerender-runtime':
case 'validation-client':
case 'generate-static-params':
return false
default:
return workUnitStore satisfies never
}
}
export type WorkUnitAsyncStorage = AsyncLocalStorage<WorkUnitStore>
export { workUnitAsyncStorageInstance as workUnitAsyncStorage }
export function throwForMissingRequestStore(callingExpression: string): never {
throw new Error(
`\`${callingExpression}\` was called outside a request scope. Read more: https://nextjs.org/docs/messages/next-dynamic-api-wrong-context`
)
}
export function throwInvariantForMissingStore(): never {
throw new InvariantError('Expected workUnitAsyncStorage to have a store.')
}
/**
* Returns the resume data cache for the given work unit store, regardless of
* whether it is mutable (`PrerenderResumeDataCache`) or read-only
* (`RenderResumeDataCache`). Use `resumeDataCache.mutable` to narrow.
*/
export function getResumeDataCache(
workUnitStore: WorkUnitStore
): ResumeDataCache | null {
switch (workUnitStore.type) {
case 'request':View on GitHub (pinned to 0ae8c72462)
Solutions
- Move the dynamic API call inside a component, route handler, or other request-scoped function so a workUnitStore is active.
- Ensure the code runs during a request (Server Component render, route handler, Server Action) rather than at module evaluation time.
- If the value is needed broadly, resolve it once within a request scope and pass it down as a prop/argument.
- For useSearchParams in Client Components, wrap usage in a Suspense boundary as required.
Example fix
// before
// const params = useSearchParams() // at module scope -> throws
// after: call inside the component (request scope)
// export default function Page() {
// const params = useSearchParams()
// return <p>{params.get('q')}</p>
// } Defensive patterns
Strategy: validation
Validate before calling
// Ensure a request store exists before calling a dynamic API.
import { headers } from 'next/headers'
function safeHeaders() {
try { return headers() } catch { return new Headers() }
}
// Better: only call within a Server Component/route handler scope. Prevention
- Call dynamic APIs only inside components/route handlers/Server Actions.
- Never call cookies/headers/searchParams at module top level.
- Pass resolved values down rather than re-fetching in non-request scope.
- Wrap Client-Component useSearchParams in a Suspense boundary.
When it happens
Trigger: Code calls a dynamic API (the `callingExpression`, e.g. 'useSearchParams', 'cookies') at module top level, inside generateStaticParams, in a utility function invoked outside a request, or during build module evaluation where no workUnitStore exists. useDynamicSearchParams checks for the store and, finding none, calls throwForMissingRequestStore.
Common situations: Calling cookies()/headers()/useSearchParams() in a shared module or outside of a component/route-handler; using dynamic APIs in a context that runs during import; refactor that moved a dynamic call out of a request-scoped component; SSR misuse where the API is called synchronously at module scope.
Related errors
- Method unavailable on `ReadonlyURLSearchParams`. Read more:
- `after` was called outside a request scope. Read more: https
AI-assisted analysis of vercel/next.js@0ae8c72462 (2026-08-06).
Data as JSON: /api/errors/08321cf0424d0e4d.
Report an issue: GitHub.