{"record":{"id":"7fa74daca8227a7c","repo":"evanw/esbuild","slug":"the-formatmessagessync-api-only-works-in-node","errorCode":null,"errorMessage":"The \"formatMessagesSync\" API only works in node","messagePattern":"The \"formatMessagesSync\" API only works in node","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"lib/npm/browser.ts","lineNumber":41,"sourceCode":"export const transform: typeof types.transform = (input: string | Uint8Array, options?: types.TransformOptions) =>\n  ensureServiceIsRunning().transform(input, options)\n\nexport const formatMessages: typeof types.formatMessages = (messages, options) =>\n  ensureServiceIsRunning().formatMessages(messages, options)\n\nexport const analyzeMetafile: typeof types.analyzeMetafile = (metafile, options) =>\n  ensureServiceIsRunning().analyzeMetafile(metafile, options)\n\nexport const buildSync: typeof types.buildSync = () => {\n  throw new Error(`The \"buildSync\" API only works in node`)\n}\n\nexport const transformSync: typeof types.transformSync = () => {\n  throw new Error(`The \"transformSync\" API only works in node`)\n}\n\nexport const formatMessagesSync: typeof types.formatMessagesSync = () => {\n  throw new Error(`The \"formatMessagesSync\" API only works in node`)\n}\n\nexport const analyzeMetafileSync: typeof types.analyzeMetafileSync = () => {\n  throw new Error(`The \"analyzeMetafileSync\" API only works in node`)\n}\n\nexport const stop = () => {\n  if (stopService) stopService()\n  return Promise.resolve()\n}\n\ninterface Service {\n  build: typeof types.build\n  context: typeof types.context\n  transform: typeof types.transform\n  formatMessages: typeof types.formatMessages\n  analyzeMetafile: typeof types.analyzeMetafile\n}","sourceCodeStart":23,"sourceCodeEnd":59,"githubUrl":"https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/lib/npm/browser.ts#L23-L59","documentation":"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.","triggerScenarios":"Application code calls esbuild.formatMessagesSync(messages, options) while running against the browser build of esbuild (esbuild-wasm or the 'browser' field).","commonSituations":"Error-formatting helpers copied from a node setup into a browser context; diagnostic tooling shared between node CLI and web UI.","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."],"exampleFix":"// before\nconst formatted = esbuild.formatMessagesSync(msgs, { kind: 'error' })\n\n// after\nconst formatted = await esbuild.formatMessages(msgs, { kind: 'error' })","handlingStrategy":"validation","validationCode":"// Use async formatting in environments that may be browser-based.\nconst isBrowserBuild =\n  typeof window !== 'undefined' && typeof window.document !== 'undefined'\n\nconst formatted = isBrowserBuild\n  ? await esbuild.formatMessages(msgs, { kind: 'error' })\n  : esbuild.formatMessagesSync(msgs, { kind: 'error' })","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["browser","sync","async","platform","wasm"],"backgroundTag":null,"analyzedSha":"f6058f8364fe7ab91ca57a83e02577ed74c9cae4","analyzedAt":"2026-08-09T18:37:22.223Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}