microsoft/monaco-editor · error · Error
You must define a function MonacoEnvironment.getWorkerUrl or
Error message
You must define a function MonacoEnvironment.getWorkerUrl or MonacoEnvironment.getWorker
What it means
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.
Source
Thrown at src/internal/common/workers.ts:87
return new Worker(
ttPolicy ? (ttPolicy.createScriptURL(workerUrl) as unknown as string) : workerUrl,
{ name: label, type: 'module' }
);
}
}
if (descriptor.createWorker) {
return descriptor.createWorker();
}
// const esmWorkerLocation = descriptor.esmModuleLocation;
// if (esmWorkerLocation) {
// const workerUrl = getWorkerBootstrapUrl(label, esmWorkerLocation.toString(true));
// const worker = new Worker(ttPolicy ? ttPolicy.createScriptURL(workerUrl) as unknown as string : workerUrl, { name: label, type: 'module' });
// return whenESMWorkerReady(worker);
// }
throw new Error(
`You must define a function MonacoEnvironment.getWorkerUrl or MonacoEnvironment.getWorker`
);
}
export function createWebWorker<T extends object>(
opts: IWebWorkerOptions
): editor.MonacoWebWorker<T> {
const worker = Promise.resolve(
getWorker({
label: opts.label ?? 'monaco-editor-worker',
moduleId: opts.moduleId,
createWorker: opts.createWorker,
})
).then((w) => {
w.postMessage('ignore');
w.postMessage(opts.createData);
return w;
});View on GitHub (pinned to ca1b42dc89)
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.
Example fix
// before — no MonacoEnvironment, language features throw on first use
import * as monaco from 'monaco-editor';
monaco.languages.typescript.typescriptDefaults.setDiagnosticsOptions({ noSemanticValidation: false });
// after (vite/esbuild)
import * as monaco from 'monaco-editor';
import editorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker';
import tsWorker from 'monaco-editor/esm/vs/language/typescript/ts.worker?worker';
self.MonacoEnvironment = {
getWorker(_, label) {
if (label === 'typescript' || label === 'javascript') return new tsWorker();
return new editorWorker();
}
}; Defensive patterns
Strategy: validation
Validate before calling
// set MonacoEnvironment before creating the editor / using language features
import editorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker';
self.MonacoEnvironment = {
getWorker(_workerId, label) {
// map labels to the right worker bundle for your bundler
return new editorWorker();
}
}; Type guard
function hasWorkerConfig(env: typeof globalThis): boolean {
const me = (env as any).MonacoEnvironment;
return !!(me && (typeof me.getWorker === 'function' || typeof me.getWorkerUrl === 'function')));
} Try / catch
try {
monaco.editor.create(...);
} catch (e) {
if (e instanceof Error && /getWorkerUrl|getWorker/.test(e.message)) {
console.error('Configure self.MonacoEnvironment.getWorker/getWorkerUrl before using language services.');
}
throw e;
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- The script at ${createData.customWorkerPath} does not add cu
- Invalid language id: ${this._languageId}
- Renaming files is not supported.
- monaco is not loaded yet
- already initialized
AI-assisted analysis of microsoft/monaco-editor@ca1b42dc89 (2026-08-13).
Data as JSON: /api/errors/a07dda25746102af.
Report an issue: GitHub.