{"record":{"id":"54c004c266632eca","repo":"vercel/next.js","slug":"after-was-called-outside-a-request-scope-read-m","errorCode":null,"errorMessage":"`after` was called outside a request scope. Read more: https://nextjs.org/docs/messages/next-dynamic-api-wrong-context","messagePattern":"`after` was called outside a request scope\\. Read more: https://nextjs\\.org/docs/messages/next-dynamic-api-wrong-context","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/next/src/server/after/after.ts","lineNumber":16,"sourceCode":"import { workAsyncStorage } from '../app-render/work-async-storage.external'\nimport { workUnitAsyncStorage } from '../app-render/work-unit-async-storage.external'\n\nexport type AfterTask<T = unknown> = Promise<T> | AfterCallback<T>\nexport type AfterCallback<T = unknown> = () => T | Promise<T>\n\n/**\n * This function allows you to schedule callbacks to be executed after the current request finishes.\n */\nexport function after<T>(task: AfterTask<T>): void {\n  const workStore = workAsyncStorage.getStore()\n  const workUnitStore = workUnitAsyncStorage.getStore()\n\n  if (!workStore || !workUnitStore) {\n    // TODO(after): the linked docs page talks about *dynamic* APIs, which after soon won't be anymore\n    throw new Error(\n      '`after` was called outside a request scope. Read more: https://nextjs.org/docs/messages/next-dynamic-api-wrong-context'\n    )\n  }\n\n  const { afterContext } = workStore\n  return afterContext.after(task, workUnitStore)\n}\n","sourceCodeStart":1,"sourceCodeEnd":24,"githubUrl":"https://github.com/vercel/next.js/blob/0ae8c72462952df163f1b1e0726641bc5b40dc93/packages/next/src/server/after/after.ts#L1-L24","documentation":"Thrown by the after() entry point when neither workAsyncStorage nor workUnitAsyncStorage has an active store, meaning after() was called outside a Next.js request scope. after() must run within a request lifecycle (route handler, server action, middleware) so it can attach deferred work to that request; calling it elsewhere has no request to defer from.","triggerScenarios":"Calling after() at module top-level, inside getStaticProps/getStaticPaths, in a utility module imported outside a request, during build time, or in an instrumentation hook. workStore and workUnitStore are both undefined in these contexts.","commonSituations":"Importing after() into a shared lib and calling it during module initialization or in a non-request function; calling after() inside a generateStaticParams or generateMetadata that runs at build time; using it in a script run via `next/script` or a worker.","solutions":["Move the after() call inside a request-scoped function: a route handler, server action, or page render.","Ensure the file calling after() is only invoked during request handling, not at import/build time.","For background work outside requests, use a dedicated task queue or cron instead of after()."],"exampleFix":"// before - called at module scope\nimport { after } from 'next/server'\nafter(() => logVisit()) // throws: outside request scope\n\n// after - called inside a route handler\nimport { after } from 'next/server'\nexport async function GET() {\n  after(() => logVisit())\n  return Response.json({ ok: true })\n}","handlingStrategy":"validation","validationCode":"// Only call after() from within a request-scoped handler.\n// In user code there is no public API to check the store; rely on call-site discipline.\nfunction assertInRequestScope() {\n  if (process.env.NEXT_BUILD === '1') throw new Error('after() must not be called at build time')\n}","typeGuard":null,"tryCatchPattern":"try {\n  after(() => log())\n} catch (err) {\n  if (err.message.includes('outside a request scope')) {\n    // not in a request; defer to a queue\n  }\n}","preventionTips":["Call after() only inside route handlers, server actions, or page render functions.","Never call after() at module top-level, in getStaticProps, or in build-time code.","Keep after() imports confined to request-handling modules."],"tags":["after","runtime","request-scope","api"],"analyzedSha":"0ae8c72462952df163f1b1e0726641bc5b40dc93","analyzedAt":"2026-08-06T19:44:29.143Z","schemaVersion":2},"datasetVersion":"2026-08-07T02:17:10.218Z"}