vuejs/vue · critical · Error
Your JavaScript runtime does not support any asynchronous pr
Error message
Your JavaScript runtime does not support any asynchronous primitives that are required by vue-server-renderer. Please use a polyfill for either Promise or setTimeout.
What it means
Thrown at module-load time by write.ts when the defer primitive cannot be resolved. defer is chosen from process.nextTick, then Promise.resolve().then, then setTimeout; if all are undefined, defer falls back to noop and the guard throws. vue-server-renderer relies on deferring render continuation to avoid stack overflows (MAX_STACK_DEPTH = 800), so without an async primitive it cannot function. This is an environment-compatibility error.
Source
Thrown at packages/server-renderer/src/write.ts:14
const MAX_STACK_DEPTH = 800
const noop = _ => _
const defer =
typeof process !== 'undefined' && process.nextTick
? process.nextTick
: typeof Promise !== 'undefined'
? fn => Promise.resolve().then(fn)
: typeof setTimeout !== 'undefined'
? setTimeout
: noop
if (defer === noop) {
throw new Error(
'Your JavaScript runtime does not support any asynchronous primitives ' +
'that are required by vue-server-renderer. Please use a polyfill for ' +
'either Promise or setTimeout.'
)
}
export function createWriteFunction(
write: (text: string, next: Function) => boolean,
onError: Function
): Function {
let stackDepth = 0
const cachedWrite = (text, next) => {
if (text && cachedWrite.caching) {
cachedWrite.cacheBuffer[cachedWrite.cacheBuffer.length - 1] += text
}
const waitForNext = write(text, next)
if (waitForNext !== true) {
if (stackDepth >= MAX_STACK_DEPTH) {View on GitHub (pinned to 9e88707940)
Solutions
- Polyfill at least one: global.Promise = require('es6-promise').Promise or global.setTimeout = ... before requiring vue-server-renderer.
- Run in a standard Node.js environment (all three primitives are native).
- If in a custom embedding, expose nextTick/setTimeout/Promise on the global scope before loading the module.
- Avoid stripping globals in security sandboxes; instead run SSR in an isolated but complete Node process.
Example fix
// before — runtime lacks async primitives, require throws
const VueSSR = require('vue-server-renderer')
// after — polyfill before require
global.Promise = global.Promise || require('core-js-pure/features/promise')
global.setTimeout = global.setTimeout || require('timers').setTimeout
const VueSSR = require('vue-server-renderer') Defensive patterns
Strategy: fallback
Validate before calling
function assertAsyncPrimitivesAvailable(): void {
const has =
(typeof process !== 'undefined' && typeof process.nextTick === 'function') ||
typeof Promise === 'function' ||
typeof setTimeout === 'function'
if (!has) {
throw new Error(
'Environment lacks process.nextTick, Promise, and setTimeout. Polyfill at least one before loading vue-server-renderer.'
)
}
}
assertAsyncPrimitivesAvailable()
require('vue-server-renderer') Type guard
function environmentSupportsAsync(): boolean {
return (
(typeof process !== 'undefined' && typeof process.nextTick === 'function') ||
typeof Promise === 'function' ||
typeof setTimeout === 'function'
)
} Try / catch
// Thrown at module-load (require) time — wrap the require in try/catch:
let VueSSR
try {
VueSSR = require('vue-server-renderer')
} catch (e) {
if (e.message.includes('does not support any asynchronous primitives')) {
global.Promise = global.Promise || require('core-js-pure/features/promise')
VueSSR = require('vue-server-renderer')
} else {
throw e
}
} Prevention
- Run SSR in a standard Node.js environment which has all three async primitives natively.
- Before loading vue-server-renderer in custom runtimes, polyfill Promise or setTimeout on the global scope.
- Do not strip globals in security sandboxes; isolate via process instead.
- Add an environment smoke test in CI that requires vue-server-renderer and catches load-time errors.
When it happens
Trigger: Loading vue-server-renderer in a JavaScript runtime that has none of: process.nextTick, native Promise, setTimeout. This is exotic — most Node and browser environments have at least one. Seen in stripped-down JS engines, some edge-case Nashorn/JVM JS runtimes, or environments where these globals were deleted/polyfill-blocked.
Common situations: Running SSR in a constrained sandbox that removes global timers/Promise for security. A JS engine embedded in a non-browser/non-Node host (e.g. a database stored-procedure JS engine) without async primitives. A bundler/misconfigured environment that tree-shook or stubbed out Promise/setTimeout.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- \n\nVue packages version mismatch:\n\n- vue@${vueVersion}\n-
- Invalid JSON bundle file: ${bundle}
- Cannot locate bundle file: ${bundle}
- Invalid server-rendering bundle format. Should be a string o
- bundle export should be a function when using { runInNewCont
AI-assisted analysis of vuejs/vue@9e88707940 (2026-08-11).
Data as JSON: /api/errors/a3ab123f2af50030.
Report an issue: GitHub.