vercel/next.js · error

Route ${workStore.route} used `headers()` inside `after()` w

Error message

Route ${workStore.route} used `headers()` inside `after()` while rendering. This is not supported. If you need this data inside an `after()` callback, use `headers()` outside of the callback. See more info here: https://nextjs.org/docs/app/api-reference/functions/after

What it means

Error "Route ${workStore.route} used `headers()` inside `after()` while rendering. This is not supported. If you need this data inside an `after()` callback, use `headers()` outside of the callback. See more info here: https://nextjs.org/docs/app/api-reference/functions/after" thrown in vercel/next.js.

Source

Thrown at packages/next/src/server/request/headers.ts:50

} from '../use-cache/use-cache-messages'

/**
 * This function allows you to read the HTTP incoming request headers in
 * [Server Components](https://nextjs.org/docs/app/building-your-application/rendering/server-components),
 * [Server Actions](https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions-and-mutations),
 * [Route Handlers](https://nextjs.org/docs/app/building-your-application/routing/route-handlers) and
 * [Middleware](https://nextjs.org/docs/app/building-your-application/routing/middleware).
 *
 * Read more: [Next.js Docs: `headers`](https://nextjs.org/docs/app/api-reference/functions/headers)
 */
export function headers(): Promise<ReadonlyHeaders> {
  const callingExpression = 'headers'
  const workStore = workAsyncStorage.getStore()
  const workUnitStore = workUnitAsyncStorage.getStore()

  if (workStore) {
    if (workUnitStore && !isRequestApiAllowedInCurrentPhase(workUnitStore)) {
      throw new Error(
        `Route ${workStore.route} used \`headers()\` inside \`after()\` while rendering. This is not supported. If you need this data inside an \`after()\` callback, use \`headers()\` outside of the callback. See more info here: https://nextjs.org/docs/app/api-reference/functions/after`
      )
    }

    if (workStore.forceStatic) {
      // When using forceStatic we override all other logic and always just return an empty
      // headers object without tracking
      const underlyingHeaders = HeadersAdapter.seal(new Headers({}))
      return makeUntrackedHeaders(underlyingHeaders)
    }

    if (workUnitStore) {
      switch (workUnitStore.type) {
        case 'cache': {
          const error = createHeadersInUseCacheError(workStore.route)
          Error.captureStackTrace(error, headers)
          applyOwnerStack(error)
          workStore.invalidDynamicUsageError ??= error

View on GitHub (pinned to 258b1c1bc0)

Solutions

  1. Read headers() before scheduling after(), and pass the values into the callback closure.
Defensive patterns

Strategy: validation

When it happens

Trigger: headers() is called inside an after() callback during render.

Common situations: Reading headers inside unstable_after; read them outside and pass values in.


AI-assisted analysis of vercel/next.js@258b1c1bc0 (2026-08-19). Data as JSON: /api/errors/32eda4cf3467c639. Report an issue: GitHub.