microsoft/monaco-editor · error · Error
The script at ${createData.customWorkerPath} does not add cu
Error message
The script at ${createData.customWorkerPath} does not add customTSWorkerFactory to self What it means
Thrown by the TypeScript worker's create() when createData.customWorkerPath is set, the script at that path was imported via self.importScripts, but the script did not assign self.customTSWorkerFactory. The customWorkerPath mechanism lets users swap the TypeScript worker class (e.g. to add extra lib files or hook tsserver) by loading a script that defines a factory on the global scope. If the script runs but doesn't register the factory, the worker cannot proceed and throws. The factory signature is (TypeScriptWorker, ts, libFileMap) => typeof TypeScriptWorker.
Source
Thrown at src/languages/features/typescript/tsWorker.ts:511
declare global {
var importScripts: (path: string) => void | undefined;
var customTSWorkerFactory: CustomTSWebWorkerFactory | undefined;
}
export function create(ctx: worker.IWorkerContext, createData: ICreateData): TypeScriptWorker {
let TSWorkerClass = TypeScriptWorker;
if (createData.customWorkerPath) {
if (typeof importScripts === 'undefined') {
console.warn(
'Monaco is not using webworkers for background tasks, and that is needed to support the customWorkerPath flag'
);
} else {
self.importScripts(createData.customWorkerPath);
const workerFactoryFunc: CustomTSWebWorkerFactory | undefined = self.customTSWorkerFactory;
if (!workerFactoryFunc) {
throw new Error(
`The script at ${createData.customWorkerPath} does not add customTSWorkerFactory to self`
);
}
TSWorkerClass = workerFactoryFunc(TypeScriptWorker, ts, libFileMap);
}
}
return new TSWorkerClass(ctx, createData);
}
/** Allows for clients to have access to the same version of TypeScript that the worker uses */
// @ts-ignore
globalThis.ts = ts.typescript;
View on GitHub (pinned to ca1b42dc89)
Solutions
- Ensure the script at customWorkerPath ends with `self.customTSWorkerFactory = (TypeScriptWorker, ts, libFileMap) => class extends TypeScriptWorker { /* overrides */ }`.
- Open the custom worker script's console — if it threw before the assignment, fix that error first.
- Confirm customWorkerPath is a URL resolvable from the worker scope and that importScripts actually loaded it (a 404 means the assignment never runs).
- If you bundled the custom worker, make sure the bundler did not rename/rewrite the `self.customTSWorkerFactory =` assignment or wrap it in a module scope where `self` is shadowed.
- Verify the factory returns a class extending TypeScriptWorker (correct arity and return type).
Example fix
// before — my-ts-worker.js exports via module syntax, never assigns self
export class MyWorker extends TypeScriptWorker {}
// after
self.customTSWorkerFactory = (TypeScriptWorker, ts, libFileMap) => {
return class MyWorker extends TypeScriptWorker {
// custom overrides here
};
}; Defensive patterns
Strategy: validation
Validate before calling
// before enabling customWorkerPath, verify the script assigns the global
// (open the script URL in a worker and check self.customTSWorkerFactory)
// example minimal correct script body:
// self.customTSWorkerFactory = (Base, ts, libs) => class extends Base {};
typescriptDefaults.setWorkerOptions({ customWorkerPath: '/assets/my-ts-worker.js' }); Type guard
function scriptRegistersFactory(): boolean {
// only meaningful inside a worker after importScripts
return typeof (self as any).customTSWorkerFactory === 'function';
} Try / catch
try {
await loadMonacoAndUseTSWorker();
} catch (e) {
if (e instanceof Error && /customTSWorkerFactory/.test(e.message)) {
console.error('The customWorkerPath script must assign self.customTSWorkerFactory.');
}
throw e;
} Prevention
- End every custom worker script with an explicit `self.customTSWorkerFactory = ...` assignment.
- Verify the script is reachable from the worker origin (no 404) and has no syntax errors.
- Avoid bundlers that scope `self` or strip global assignments; build the custom worker as an IIFE that writes to self.
When it happens
Trigger: Setting monaco.languages.typescript.typescriptDefaults.setWorkerOptions({ customWorkerPath: './my-ts-worker.js' }) where my-ts-worker.js exists and loads but does not execute `self.customTSWorkerFactory = ...`; the script threw before reaching the assignment; the script assigns under a different global name.
Common situations: Custom worker script has a syntax/runtime error that aborts before the assignment; author forgot the `self.customTSWorkerFactory =` line; the path points to a script that exports via module syntax instead of assigning to self; bundling the custom worker stripped the global assignment.
Related errors
- You must define a function MonacoEnvironment.getWorkerUrl or
- Renaming files is not supported.
- Invalid language id: ${this._languageId}
- monaco is not loaded yet
- already initialized
AI-assisted analysis of microsoft/monaco-editor@ca1b42dc89 (2026-08-13).
Data as JSON: /api/errors/8d3e5c2329ad310c.
Report an issue: GitHub.