evanw/esbuild · error · Error
The "formatMessagesSync" API only works in node
Error message
The "formatMessagesSync" API only works in node
What it means
The browser entry of esbuild (lib/npm/browser.ts) defines formatMessagesSync as a stub that always throws. Since the browser build communicates with a WebAssembly service asynchronously, no synchronous formatting API is possible.
Solutions
- Switch to esbuild.formatMessages(...) and await the result.
- Run under the native esbuild package in node if the synchronous variant is needed.
- Cache formatted messages from an async pre-pass instead of formatting synchronously at render time.
Example fix
// before
const formatted = esbuild.formatMessagesSync(msgs, { kind: 'error' })
// after
const formatted = await esbuild.formatMessages(msgs, { kind: 'error' }) Defensive patterns
Strategy: validation
Validate before calling
// Use async formatting in environments that may be browser-based.
const isBrowserBuild =
typeof window !== 'undefined' && typeof window.document !== 'undefined'
const formatted = isBrowserBuild
? await esbuild.formatMessages(msgs, { kind: 'error' })
: esbuild.formatMessagesSync(msgs, { kind: 'error' }) Prevention
- Format messages asynchronously in shared code.
- Pre-format in a node build step and ship the strings if the browser only needs to render them.
- Avoid formatMessagesSync in any module imported by a browser bundle.
When it happens
Trigger: Application code calls esbuild.formatMessagesSync(messages, options) while running against the browser build of esbuild (esbuild-wasm or the 'browser' field).
Common situations: Error-formatting helpers copied from a node setup into a browser context; diagnostic tooling shared between node CLI and web UI.
Related errors
- The "analyzeMetafileSync" API only works in node
- The "buildSync" API only works in node
- The "transformSync" API only works in node
- You need to wait for the promise returned from "initialize"…
- Cannot use the "serve" API in this environment
AI-assisted analysis of evanw/esbuild@f6058f8364 (2026-08-09).
Data as JSON: /api/errors/7fa74daca8227a7c.
Report an issue: GitHub.
Appendix: source
Thrown at lib/npm/browser.ts:41
export const transform: typeof types.transform = (input: string | Uint8Array, options?: types.TransformOptions) =>
ensureServiceIsRunning().transform(input, options)
export const formatMessages: typeof types.formatMessages = (messages, options) =>
ensureServiceIsRunning().formatMessages(messages, options)
export const analyzeMetafile: typeof types.analyzeMetafile = (metafile, options) =>
ensureServiceIsRunning().analyzeMetafile(metafile, options)
export const buildSync: typeof types.buildSync = () => {
throw new Error(`The "buildSync" API only works in node`)
}
export const transformSync: typeof types.transformSync = () => {
throw new Error(`The "transformSync" API only works in node`)
}
export const formatMessagesSync: typeof types.formatMessagesSync = () => {
throw new Error(`The "formatMessagesSync" API only works in node`)
}
export const analyzeMetafileSync: typeof types.analyzeMetafileSync = () => {
throw new Error(`The "analyzeMetafileSync" API only works in node`)
}
export const stop = () => {
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
}View on GitHub (pinned to f6058f8364)