{"record":{"id":"a07dda25746102af","repo":"microsoft/monaco-editor","slug":"you-must-define-a-function-monacoenvironment-getwo","errorCode":null,"errorMessage":"You must define a function MonacoEnvironment.getWorkerUrl or MonacoEnvironment.getWorker","messagePattern":"You must define a function MonacoEnvironment\\.getWorkerUrl or MonacoEnvironment\\.getWorker","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/internal/common/workers.ts","lineNumber":87,"sourceCode":"\t\t\treturn new Worker(\n\t\t\t\tttPolicy ? (ttPolicy.createScriptURL(workerUrl) as unknown as string) : workerUrl,\n\t\t\t\t{ name: label, type: 'module' }\n\t\t\t);\n\t\t}\n\t}\n\n\tif (descriptor.createWorker) {\n\t\treturn descriptor.createWorker();\n\t}\n\n\t// const esmWorkerLocation = descriptor.esmModuleLocation;\n\t// if (esmWorkerLocation) {\n\t// \tconst workerUrl = getWorkerBootstrapUrl(label, esmWorkerLocation.toString(true));\n\t// \tconst worker = new Worker(ttPolicy ? ttPolicy.createScriptURL(workerUrl) as unknown as string : workerUrl, { name: label, type: 'module' });\n\t// \treturn whenESMWorkerReady(worker);\n\t// }\n\n\tthrow new Error(\n\t\t`You must define a function MonacoEnvironment.getWorkerUrl or MonacoEnvironment.getWorker`\n\t);\n}\n\nexport function createWebWorker<T extends object>(\n\topts: IWebWorkerOptions\n): editor.MonacoWebWorker<T> {\n\tconst worker = Promise.resolve(\n\t\tgetWorker({\n\t\t\tlabel: opts.label ?? 'monaco-editor-worker',\n\t\t\tmoduleId: opts.moduleId,\n\t\t\tcreateWorker: opts.createWorker,\n\t\t})\n\t).then((w) => {\n\t\tw.postMessage('ignore');\n\t\tw.postMessage(opts.createData);\n\t\treturn w;\n\t});","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/microsoft/monaco-editor/blob/ca1b42dc896b99db78e1c743256e8654e12cea2d/src/internal/common/workers.ts#L69-L105","documentation":"Thrown by Monaco's worker factory when it cannot construct a Web Worker for a language service. The factory first looks for self.MonacoEnvironment.getWorker, then MonacoEnvironment.getWorkerUrl, then falls back to descriptor.createWorker; if none is provided it throws. Web Workers host the heavy language services (TypeScript, CSS, HTML, JSON), so this error means language intelligence cannot start. The check is per-worker-creation, triggered lazily the first time a language feature needs a worker.","triggerScenarios":"Embedding Monaco with an AMD or custom loader without setting window.MonacoEnvironment; using a bundler (webpack/vite/esbuild) that doesn't know how to emit Monaco's worker bundles; loading only `editor.main` without a worker strategy; calling createWebWorker directly without a createWorker option and without a MonacoEnvironment hook.","commonSituations":"First time integrating Monaco into a webpack/vite app and forgetting the worker plugin; using the AMD loader in a CSP that blocks worker script URLs; switching from a bundler setup that auto-configured workers to a plain `<script>` setup; deploying to an environment where MonacoEnvironment was set on the wrong global.","solutions":["For webpack, install and use `monaco-editor-webpack-plugin` which injects getWorkerUrl automatically.","For vite/esbuild, set `self.MonacoEnvironment = { getWorker(_, label) { return new Worker(new URL(`monaco-editor/esm/vs/language/${...}/${label}.worker?worker`, import.meta.url), { type: 'module' }); } }` using the bundler's `?worker` import.","For AMD loader, set `window.MonacoEnvironment = { getWorkerUrl: (moduleId, label) => `./vs/base/worker/workerMain.js` }` pointing at the bundled worker file.","If using createWebWorker directly, pass a `createWorker: () => new Worker(...)` option so the factory uses that instead of MonacoEnvironment.","Verify MonacoEnvironment is set on the same global Monaco reads (globalThis/self/window) before any language mode activates."],"exampleFix":"// before — no MonacoEnvironment, language features throw on first use\nimport * as monaco from 'monaco-editor';\nmonaco.languages.typescript.typescriptDefaults.setDiagnosticsOptions({ noSemanticValidation: false });\n// after (vite/esbuild)\nimport * as monaco from 'monaco-editor';\nimport editorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker';\nimport tsWorker from 'monaco-editor/esm/vs/language/typescript/ts.worker?worker';\nself.MonacoEnvironment = {\n  getWorker(_, label) {\n    if (label === 'typescript' || label === 'javascript') return new tsWorker();\n    return new editorWorker();\n  }\n};","handlingStrategy":"validation","validationCode":"// set MonacoEnvironment before creating the editor / using language features\nimport editorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker';\nself.MonacoEnvironment = {\n  getWorker(_workerId, label) {\n    // map labels to the right worker bundle for your bundler\n    return new editorWorker();\n  }\n};","typeGuard":"function hasWorkerConfig(env: typeof globalThis): boolean {\n  const me = (env as any).MonacoEnvironment;\n  return !!(me && (typeof me.getWorker === 'function' || typeof me.getWorkerUrl === 'function')));\n}","tryCatchPattern":"try {\n  monaco.editor.create(...);\n} catch (e) {\n  if (e instanceof Error && /getWorkerUrl|getWorker/.test(e.message)) {\n    console.error('Configure self.MonacoEnvironment.getWorker/getWorkerUrl before using language services.');\n  }\n  throw e;\n}","preventionTips":["Always set self.MonacoEnvironment at app entry, before any monaco.languages.* call.","Use the official bundler plugins (monaco-editor-webpack-plugin, or `?worker` imports in vite/esbuild).","Write a smoke test that opens a TS/CSS model and asserts no worker error is logged."],"tags":["runtime","web-worker","bundler","monaco-environment","language-services"],"backgroundTag":null,"analyzedSha":"ca1b42dc896b99db78e1c743256e8654e12cea2d","analyzedAt":"2026-08-13T02:00:51.380Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}