Monaco Editor Web Worker always fails with 404 due to missing MonacoEnvironment.getWorkerUrl configuration
- Dominant language
- TypeScript
- Stars
- 156k
- Forks
- 24.6k
- Avg merge
- 22h 9m
- Merged PRs (30d)
- 610
Description
## Self Checks
- [x] I have read the [Contributing Guide](https://github.com/langgenius/dify/blob/main/CONTRIBUTING.md) and [Language Policy](https://github.com/langgenius/dify/issues/1542).
- [x] This is only for bug report, if you would like to ask a question, please head to [Discussions](https://github.com/langgenius/dify/discussions/categories/general).
- [x] I have searched for existing issues [search for existing issues](https://github.com/langgenius/dify/issues), including closed ones.
- [x] I confirm that I am using English to submit this report, otherwise it will be closed.
- [x] 【中文用户 & Non English User】请使用英语提交,否则会被关闭 :)
- [x] Please do not modify this template :) and fill in all the required fields.
## Dify version
1.14.2
## Cloud or Self Hosted
Self Hosted (Docker), Self Hosted (Source)
## Bug Description
Monaco Editor's Web Worker always fails to load, causing it to fall back to the main thread (fake worker mode) every time the workflow editor is opened.
## Root Cause
In `web/app/components/workflow/nodes/_base/components/editor/code-editor/index.tsx` (line 17-18), the Monaco loader is configured with a local path:
```typescript
if (typeof window !== 'undefined')
loader.config({ paths: { vs: `${window.location.origin}${basePath}/vs` } })
```
However, `MonacoEnvironment.getWorkerUrl` is not configured. Without this, Monaco Editor uses the default worker loading logic, which appends the worker label as a URL fragment:
```
GET /vs/base/worker/workerMain.js#editorWorkerService
```
The browser encodes `#` to `%23` in the HTTP request:
```
GET /vs/base/worker/workerMain.js%23editorWorkerService
```
The server cannot find this path and returns a 404. The worker fails to initialize, and Monaco Editor falls back to running on the main thread.
## Impact
1. **Performance**: The 404 response triggers SSR rendering of a full 404 page (~350KB HTML, 100-700ms per request).
2. **Functionality**: Syntax checking, code formatting, and other worker-dependent features run on the main thread instead of a Web Worker, which may cause UI stuttering with large files.
3. **Unnecessary network traffic**: Each editor load generates a 350KB 404 response that serves no purpose.
## Evidence
Nginx access logs show the pattern:
```
GET /vs/base/worker/workerMain.js%23editorWorkerService 404 91901 rt=0.733
GET /vs/base/worker/workerMain.js 304 0 rt=0.002
```
- `workerMain.js` (without `#`): loads successfully, 304, 2ms
- `workerMain.js%23editorWorkerService` (with encoded `#`): 404, 733ms, 91KB response
Worker types affected:
- `editorWorkerService`: 72 occurrences
- `json`: 8 occurrences
A GitHub code search for `MonacoEnvironment` and `getWorkerUrl` in this repo returns 0 results, confirming this configuration is missing.
## Suggested Fix
Add `MonacoEnvironment.getWorkerUrl` configuration after the loader config:
```typescript
if (typeof window !== 'undefined') {
loader.config({ paths: { vs: `${window.location.origin}${basePath}/vs` } })
self.MonacoEnvironment = {
getWorkerUrl: () => `${window.location.origin}${basePath}/vs/base/worker/workerMain.js`,
}
}
```
This returns the worker URL without the `#label` fragment. The worker name is passed via the `name` parameter of `new Worker(url, { name: label })`, which Monaco Editor already does internally.
## Environment
- Dify version: 1.14.2
- Deployment: Kubernetes, self-hosted
- Browser: Chrome/Safari/Firefox (all affected)
- Monaco Editor: bundled in `/vs/`
Contributor guide
Research direction
Start in web/app/components/workflow/nodes/_base/components/editor/code-editor/index.tsx and inspect the existing Monaco loader configuration and worker setup. Configure the worker URL as described, then verify in browser network logs that worker requests no longer contain the encoded label fragment or return 404, and that Monaco workers load instead of fake-worker mode.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- frontend
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 78/100