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

  1. For webpack, install and use `monaco-editor-webpack-plugin` which injects getWorkerUrl automatically.
  2. 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.
  3. For AMD loader, set `window.MonacoEnvironment = { getWorkerUrl: (moduleId, label) => `./vs/base/worker/workerMain.js` }` pointing at the bundled worker file.
  4. If using createWebWorker directly, pass a `createWorker: () => new Worker(...)` option so the factory uses that instead of MonacoEnvironment.
  5. 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

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


AI-assisted analysis of microsoft/monaco-editor@ca1b42dc89 (2026-08-13). Data as JSON: /api/errors/a07dda25746102af. Report an issue: GitHub.