evanw/esbuild · error · Error
You need to wait for the promise returned from "initialize"…
Error message
You need to wait for the promise returned from "initialize" to be resolved before calling this
What it means
In the browser build (lib/npm/browser.ts:65-69), ensureServiceIsRunning() throws this specific message when initialize() has been called (so initializePromise is set) but has not yet resolved (longLivedService is still undefined), and an API method like build/transform is invoked in between. esbuild requires the WASM service to be fully booted before any call because WebAssembly instantiation is asynchronous.
Solutions
- Await the promise returned by initialize before any other esbuild call.
- Chain subsequent calls in a .then() on initialize if top-level await is unavailable.
- Centralize initialization in an async bootstrap function that all esbuild usage goes through.
Example fix
// before
esbuild.initialize({ wasmURL: '/esbuild.wasm' })
esbuild.build({ entryPoints: ['a.ts'] }) // throws
// after
await esbuild.initialize({ wasmURL: '/esbuild.wasm' })
await esbuild.build({ entryPoints: ['a.ts'] }) Defensive patterns
Strategy: validation
Validate before calling
// Track initialization state and never call APIs before it resolves.
let ready: Promise<void>
async function boot() {
ready = esbuild.initialize({ wasmURL: '/esbuild.wasm' })
await ready
}
async function safeBuild(opts) {
if (!ready) throw new Error('esbuild not initialized')
await ready // ensure the service is up
return esbuild.build(opts)
} Try / catch
// If you cannot await statically, catch and retry after initialize resolves.
try {
await esbuild.build(opts)
} catch (e) {
if (/wait for the promise returned from "initialize"/.test(String(e?.message))) {
await esbuildInitializePromise // the promise from initialize()
await esbuild.build(opts)
} else {
throw e
}
} Prevention
- Always `await esbuild.initialize(...)` as the first esbuild operation.
- Route all esbuild calls through a single async bootstrap that guarantees readiness.
- Treat initialize() like an async constructor: nothing else may run until it resolves.
When it happens
Trigger: Calling esbuild.build(...)/transform(...)/etc. immediately after esbuild.initialize({...}) without awaiting the promise initialize returns, while running the browser/WASM build.
Common situations: Forgetting to await initialize at module top level; sequential statements in non-async code that call initialize then build; refactoring from node (where the service auto-starts) to browser without adding the await.
Related errors
- Must provide either the "wasmURL" option or the…
- The "analyzeMetafileSync" API only works in node
- The "buildSync" API only works in node
- The "formatMessagesSync" API only works in node
- The "transformSync" API only works in node
AI-assisted analysis of evanw/esbuild@f6058f8364 (2026-08-09).
Data as JSON: /api/errors/cb09308b25be5e3a.
Report an issue: GitHub.
Appendix: source
Thrown at lib/npm/browser.ts:67
if (stopService) stopService()
return Promise.resolve()
}
interface Service {
build: typeof types.build
context: typeof types.context
transform: typeof types.transform
formatMessages: typeof types.formatMessages
analyzeMetafile: typeof types.analyzeMetafile
}
let initializePromise: Promise<void> | undefined
let stopService: (() => void) | undefined
let longLivedService: Service | undefined
let ensureServiceIsRunning = (): Service => {
if (longLivedService) return longLivedService
if (initializePromise) throw new Error('You need to wait for the promise returned from "initialize" to be resolved before calling this')
throw new Error('You need to call "initialize" before calling this')
}
export const initialize: typeof types.initialize = options => {
options = common.validateInitializeOptions(options || {})
let wasmURL = options.wasmURL
let wasmModule = options.wasmModule
let useWorker = options.worker !== false
if (!wasmURL && !wasmModule) throw new Error('Must provide either the "wasmURL" option or the "wasmModule" option')
if (initializePromise) throw new Error('Cannot call "initialize" more than once')
initializePromise = startRunningService(wasmURL || '', wasmModule, useWorker)
initializePromise.catch(() => {
// Let the caller try again if this fails
initializePromise = void 0
})
return initializePromise
}
View on GitHub (pinned to f6058f8364)