vercel/next.js · error · Error

`after` was called outside a request scope. Read more: https

Error message

`after` was called outside a request scope. Read more: https://nextjs.org/docs/messages/next-dynamic-api-wrong-context

What it means

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.

Source

Thrown at packages/next/src/server/after/after.ts:16

import { workAsyncStorage } from '../app-render/work-async-storage.external'
import { workUnitAsyncStorage } from '../app-render/work-unit-async-storage.external'

export type AfterTask<T = unknown> = Promise<T> | AfterCallback<T>
export type AfterCallback<T = unknown> = () => T | Promise<T>

/**
 * This function allows you to schedule callbacks to be executed after the current request finishes.
 */
export function after<T>(task: AfterTask<T>): void {
  const workStore = workAsyncStorage.getStore()
  const workUnitStore = workUnitAsyncStorage.getStore()

  if (!workStore || !workUnitStore) {
    // TODO(after): the linked docs page talks about *dynamic* APIs, which after soon won't be anymore
    throw new Error(
      '`after` was called outside a request scope. Read more: https://nextjs.org/docs/messages/next-dynamic-api-wrong-context'
    )
  }

  const { afterContext } = workStore
  return afterContext.after(task, workUnitStore)
}

View on GitHub (pinned to 0ae8c72462)

Solutions

  1. Move the after() call inside a request-scoped function: a route handler, server action, or page render.
  2. Ensure the file calling after() is only invoked during request handling, not at import/build time.
  3. For background work outside requests, use a dedicated task queue or cron instead of after().

Example fix

// before - called at module scope
import { after } from 'next/server'
after(() => logVisit()) // throws: outside request scope

// after - called inside a route handler
import { after } from 'next/server'
export async function GET() {
  after(() => logVisit())
  return Response.json({ ok: true })
}
Defensive patterns

Strategy: validation

Validate before calling

// Only call after() from within a request-scoped handler.
// In user code there is no public API to check the store; rely on call-site discipline.
function assertInRequestScope() {
  if (process.env.NEXT_BUILD === '1') throw new Error('after() must not be called at build time')
}

Try / catch

try {
  after(() => log())
} catch (err) {
  if (err.message.includes('outside a request scope')) {
    // not in a request; defer to a queue
  }
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of vercel/next.js@0ae8c72462 (2026-08-06). Data as JSON: /api/errors/54c004c266632eca. Report an issue: GitHub.