{"record":{"id":"09add2c77e9a87f4","repo":"vercel/next.js","slug":"after-will-not-work-correctly-because-waitun","errorCode":null,"errorMessage":"`after()` will not work correctly, because `waitUntil` is not available in the current environment.","messagePattern":"`after\\(\\)` will not work correctly, because `waitUntil` is not available in the current environment\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/next/src/server/after/after-context.ts","lineNumber":193,"sourceCode":"      // this is very defensive, but we really don't want anything to blow up in an error handler\n      try {\n        this.onTaskError?.(error)\n      } catch (handlerError) {\n        console.error(\n          new InvariantError(\n            '`onTaskError` threw while handling an error thrown from an `after` task',\n            {\n              cause: handlerError,\n            }\n          )\n        )\n      }\n    }\n  }\n}\n\nfunction errorWaitUntilNotAvailable(): never {\n  throw new Error(\n    '`after()` will not work correctly, because `waitUntil` is not available in the current environment.'\n  )\n}\n","sourceCodeStart":175,"sourceCodeEnd":197,"githubUrl":"https://github.com/vercel/next.js/blob/0ae8c72462952df163f1b1e0726641bc5b40dc93/packages/next/src/server/after/after-context.ts#L175-L197","documentation":"Thrown by errorWaitUntilNotAvailable() (via addThenable/addCallback) when after() is called but the current runtime does not provide a `waitUntil` function. after() relies on the platform's waitUntil to keep the process alive after the response is sent; without it deferred work would be killed when the request ends. This is an environment capability error.","triggerScenarios":"Calling after() in a runtime/adapter that did not supply waitUntil in RequestLifecycleOpts (e.g. a minimal custom server, an unsupported serverless adapter, or running a route handler outside the standard Next.js request lifecycle). Both the Promise and callback code paths check `if (!this.waitUntil)` and throw.","commonSituations":"Using a custom Node.js server or an older/unsupported platform adapter that doesn't implement waitUntil; invoking route logic in a test harness without the full Next.js server; deploying to an environment where the request lifecycle hooks aren't wired.","solutions":["Run the code under the standard Next.js server (next dev / next start) or a supported adapter that provides waitUntil.","Avoid calling after() in custom-server or standalone scripts that bypass the request lifecycle.","If you must defer work in an unsupported environment, use your own background queue instead of after()."],"exampleFix":"// before: custom server without waitUntil\nafter(() => syncDb()) // throws\n// after: run under next start, or use a manual queue\nprocess.nextTick(() => syncDb()) // only if you accept it may be killed","handlingStrategy":"validation","validationCode":"// before calling after(), confirm the environment provides waitUntil\nfunction hasWaitUntil(): boolean {\n  // This is framework-internal; in user code, gate after() usage on running under next start/dev\n  return process.env.NEXT_RUNTIME !== undefined\n}","typeGuard":null,"tryCatchPattern":"try {\n  after(() => doWork())\n} catch (err) {\n  if (err.message.includes('waitUntil is not available')) {\n    // schedule work via your own background queue instead\n  }\n}","preventionTips":["Only call after() when running under the standard Next.js server.","Do not use after() in custom servers or standalone scripts.","If waitUntil is unavailable, use a dedicated worker/queue for deferred work."],"tags":["after","runtime","serverless","waituntil"],"analyzedSha":"0ae8c72462952df163f1b1e0726641bc5b40dc93","analyzedAt":"2026-08-06T19:44:29.143Z","schemaVersion":2},"datasetVersion":"2026-08-07T02:17:10.218Z"}