FIX: Compile missing rollup plugin bundles on demand in development

In #38658 , rollup plugin compiler is enabled by default, however, a plugin can disappear if its generated manifest entry is missing or stale, e.g. Chat plugin.

This commit adds the logic using the existing manifest lookup path to compile the plugin bundle on demand in development, then retry the lookup, preventing plugins like chat from silently failing to load in local dev after the rollup switch.

Also, a failing spec is added to guard against regression.


Before:

Even if the plugin is enabled, nothing happened in dev container.

After:

2 Likes

Plugin assets are compiled automatically when you boot the server in development mode. That’s the “[PluginJsWatcher]” line in the log you screenshotted. We deliberately designed the system to happen in the background, rather than making the compilation happen during web requests.

Many of our team have been using this system in development for the last few weeks, so there must be something specific about your system which is causing it to fail. :thinking:

How are you starting your server? Do you have any unusual environment variables set?

I started the server using devcontainer, updated it from a previous version using git pull, and then use ctrl+shift+b to start the server, then the plugin is nerver compiled when started.

No environment variables set.

In the console, did you see the [PluginJsWatcher] lines? Did you see something like [Plugin::JsManager] Finished initial compilation of plugins in 5.9s ?

Before the change, no.

The server just started with ready, but the chat is not compiled.

I’ll upload a screen record.

1 Like

Seem the video too large.

Try this: removing /app/assets/generated

The console shows the following, but chat is never compiled.

Ember CLI running on PID: 3456
Starting CSS change watcher
[ember-cli] Proxying to http://127.0.0.1:3000
[ember-cli] building... 
[ember-cli] ...[BroccoliMergeFiles]
I, [2026-03-20T09:47:37.703686 #3481]  INFO -- : listening on addr=127.0.0.1:3000 fd=38
[ember-cli] ...[ConfigLoader]
[ember-cli] ...[Babel: ember-tracked-storage-polyfill > applyPatches]
[ember-cli] ...[Babel: pretty-text > applyPatches]
I, [2026-03-20T09:47:43.338485 #3466]  INFO -- : mold gen=0 pid=3481 ready
I, [2026-03-20T09:47:43.340508 #3466]  INFO -- : monitor pid=3466 ready
I, [2026-03-20T09:47:43.340654 #3466]  INFO -- : monitor process ready
I, [2026-03-20T09:47:43.361234 #3481]  INFO -- : service gen=0 spawning...
I, [2026-03-20T09:47:44.817214 #3481]  INFO -- : worker=0 gen=0 spawning...
[ember-cli] ...[Babel: @embroider/macros > applyPatches]
[ember-cli] ...[Babel: ember-this-fallback > applyPatches]
I, [2026-03-20T09:47:46.412287 #3466]  INFO -- : service gen=0 pid=4278 spawned
I, [2026-03-20T09:47:46.413532 #4278]  INFO -- : starting 1 supervised sidekiqs
I, [2026-03-20T09:47:46.716314 #3481]  INFO -- : worker=1 gen=0 spawning...
I, [2026-03-20T09:47:48.556407 #3466]  INFO -- : worker=0 gen=0 pid=4316 registered
I, [2026-03-20T09:47:48.610839 #4316]  INFO -- : worker=0 gen=0 pid=4316 ready
I, [2026-03-20T09:47:48.651842 #3481]  INFO -- : worker=2 gen=0 spawning...
I, [2026-03-20T09:47:50.233024 #3466]  INFO -- : worker=1 gen=0 pid=4371 registered
I, [2026-03-20T09:47:50.514859 #4371]  INFO -- : worker=1 gen=0 pid=4371 ready
I, [2026-03-20T09:47:50.758417 #4381]  INFO -- : Loading Sidekiq in process id 4381
I, [2026-03-20T09:47:52.373478 #3466]  INFO -- : worker=2 gen=0 pid=4413 registered
I, [2026-03-20T09:47:52.452613 #4413]  INFO -- : worker=2 gen=0 pid=4413 ready
[ember-cli] ...[@embroider/compat/app]
writing pid file /workspace/discourse/tmp/pids/plugin_js_watcher_0.pid for 4554
I, [2026-03-20T09:47:54.484062 #4554]  INFO -- : [PluginJsWatcher] Loading PluginJsWatcher in process id 4554
[ember-cli] ...[@embroider/webpack]
[Plugin::JsManager] Compiling 43 plugins...
[ember-cli] ...[@embroider/webpack]
[ember-cli] ...[@embroider/webpack]
[ember-cli] file added checklist
[ember-cli] ...[@embroider/webpack]
[ember-cli] ...[@embroider/webpack]
[ember-cli] ...[@embroider/webpack]
Finished Plugin JS watcher thread
/workspace/discourse/lib/asset_processor.rb:169:in 'MiniRacer::Context#call': terminated (MiniRacer::ScriptTerminatedError)
        from /workspace/discourse/lib/asset_processor.rb:169:in 'block in AssetProcessor.v8_call'
        from /workspace/discourse/lib/asset_processor.rb:168:in 'Thread::Mutex#synchronize'
        from /workspace/discourse/lib/asset_processor.rb:168:in 'AssetProcessor.v8_call'
        from /workspace/discourse/lib/asset_processor.rb:244:in 'AssetProcessor#rollup'
        from /workspace/discourse/lib/plugin/js_compiler.rb:21:in 'Plugin::JsCompiler#compile!'
        from /workspace/discourse/lib/plugin/js_manager.rb:132:in 'Plugin::JsManager#compile_js_bundle'
        from /workspace/discourse/lib/plugin/js_manager.rb:57:in 'block in Plugin::JsManager#compile!'
        from /home/discourse/.bundle/gems/ruby/3.4.0/gems/parallel-1.27.0/lib/parallel.rb:650:in 'Parallel.call_with_index'
        from /home/discourse/.bundle/gems/ruby/3.4.0/gems/parallel-1.27.0/lib/parallel.rb:620:in 'Parallel.process_incoming_jobs'
        from /home/discourse/.bundle/gems/ruby/3.4.0/gems/parallel-1.27.0/lib/parallel.rb:600:in 'block in Parallel.worker'
        from /home/discourse/.bundle/gems/ruby/3.4.0/gems/parallel-1.27.0/lib/parallel.rb:591:in 'Process.fork'
        from /home/discourse/.bundle/gems/ruby/3.4.0/gems/parallel-1.27.0/lib/parallel.rb:591:in 'Parallel.worker'
        from /home/discourse/.bundle/gems/ruby/3.4.0/gems/parallel-1.27.0/lib/parallel.rb:582:in 'block in Parallel.create_workers'
        from /home/discourse/.bundle/gems/ruby/3.4.0/gems/parallel-1.27.0/lib/parallel.rb:581:in 'Array#each'
        from /home/discourse/.bundle/gems/ruby/3.4.0/gems/parallel-1.27.0/lib/parallel.rb:581:in 'Enumerable#each_with_index'
        from /home/discourse/.bundle/gems/ruby/3.4.0/gems/parallel-1.27.0/lib/parallel.rb:581:in 'Parallel.create_workers'
        from /home/discourse/.bundle/gems/ruby/3.4.0/gems/parallel-1.27.0/lib/parallel.rb:520:in 'Parallel.work_in_processes'
        from /home/discourse/.bundle/gems/ruby/3.4.0/gems/parallel-1.27.0/lib/parallel.rb:291:in 'Parallel.map'
        from /home/discourse/.bundle/gems/ruby/3.4.0/gems/parallel-1.27.0/lib/parallel.rb:235:in 'Parallel.each'
        from /workspace/discourse/lib/plugin/js_manager.rb:56:in 'Plugin::JsManager#compile!'
        from /workspace/discourse/lib/plugin/js_manager.rb:190:in 'Plugin::JsManager#watch'
        from /workspace/discourse/lib/demon/plugin_js_watcher.rb:17:in 'Demon::PluginJsWatcher#after_fork'
        from /workspace/discourse/lib/demon/base.rb:188:in 'block in Demon::Base#run'
        from /workspace/discourse/lib/demon/base.rb:184:in 'Kernel#fork'
        from /workspace/discourse/lib/demon/base.rb:184:in 'Demon::Base#run'
        from /workspace/discourse/lib/demon/base.rb:177:in 'Demon::Base#start'
        from /workspace/discourse/lib/demon/base.rb:30:in 'block in Demon::Base.start'
        from <internal:numeric>:257:in 'Integer#times'
        from /workspace/discourse/lib/demon/base.rb:30:in 'Demon::Base.start'
        from /workspace/discourse/config/pitchfork.conf.rb:126:in 'block in Pitchfork::Configurator#load'
        from /home/discourse/.bundle/gems/ruby/3.4.0/gems/pitchfork-0.18.2/lib/pitchfork/http_server.rb:631:in 'Pitchfork::HttpServer#service_loop'
        from /home/discourse/.bundle/gems/ruby/3.4.0/gems/pitchfork-0.18.2/lib/pitchfork/http_server.rb:680:in 'block in Pitchfork::HttpServer#spawn_service'
        from /home/discourse/.bundle/gems/ruby/3.4.0/gems/pitchfork-0.18.2/lib/pitchfork/http_server.rb:1222:in 'block in Pitchfork::HttpServer#fork_sibling'
        from /home/discourse/.bundle/gems/ruby/3.4.0/gems/pitchfork-0.18.2/lib/pitchfork.rb:170:in 'block in Pitchfork.clean_fork'
        from /home/discourse/.bundle/gems/ruby/3.4.0/gems/pitchfork-0.18.2/lib/pitchfork.rb:168:in 'Kernel#catch'
        from /home/discourse/.bundle/gems/ruby/3.4.0/gems/pitchfork-0.18.2/lib/pitchfork.rb:168:in 'Pitchfork.clean_fork'
        from /home/discourse/.bundle/gems/ruby/3.4.0/gems/pitchfork-0.18.2/lib/pitchfork/http_server.rb:690:in 'Pitchfork::HttpServer#spawn_initial_mold'
        from /home/discourse/.bundle/gems/ruby/3.4.0/gems/pitchfork-0.18.2/lib/pitchfork/http_server.rb:176:in 'Pitchfork::HttpServer#start'
        from /home/discourse/.bundle/gems/ruby/3.4.0/gems/pitchfork-0.18.2/exe/pitchfork:110:in '<top (required)>'
        from /workspace/discourse/bin/pitchfork:58:in 'Kernel#load'
        from /workspace/discourse/bin/pitchfork:58:in 'block in <main>'
        from /workspace/discourse/bin/pitchfork:58:in 'Kernel#fork'
        from /workspace/discourse/bin/pitchfork:58:in '<main>'
[ember-cli] ...[@embroider/webpack]
[ember-cli] ...[@embroider/webpack]
[ember-cli] ...[@embroider/webpack]
[ember-cli] ...[Babel: discourse > applyPatches]
[ember-cli] 
[ember-cli] Build successful (105607ms) – Serving on http://localhost:4200/
[ember-cli] 
[ember-cli] Slowest Nodes (totalTime >= 5%) | Total (avg)
[ember-cli] -+-
[ember-cli] @embroider/webpack (1) | 86394ms
[ember-cli] @embroider/compat/app (1) | 6764ms
[ember-cli] Babel: pretty-text (1) | 5364ms
[ember-cli] 
[ember-cli] building... 
[ember-cli] ...[@embroider/webpack]
[ember-cli] 
[ember-cli] Build successful (4541ms) – Serving on http://localhost:4200/
[ember-cli] 
[ember-cli] Slowest Nodes (totalTime >= 5%) | Total (avg)
[ember-cli] -+-
[ember-cli] @embroider/webpack (1) | 2508ms
[ember-cli] Funnel (179) | 1005ms (5 ms)
[ember-cli] @embroider/compat/app (1) | 415ms
[ember-cli] broccoli-persistent-filter:Mapper (3) | 353ms (117 ms)
[ember-cli] 

Aha, thanks!

It looks like the initial compilation of chat is timing out on your machine. Let’s increase that, so that it works better in slower environments:

If you’re able to make more CPU/memory resources available in your docker environment, that’ll improve your development experience. But at least this increase should make it work.

2 Likes