title: WebAssembly: worker.js onmessage() captured an uncaught exception: NetworkError: Failed to execute 'importScripts' on 'WorkerGlobalScope'
body: <p>I have a working C++ static library that I'm porting to WebAssembly using Emscripten. Right now, I'm trying to get its existing unit tests running.</p>
  <p>I'm using the following Python script to serve the HTML file Emscripten generated.</p>
  <pre class="lang-py prettyprint-override"><code>#!/usr/bin/env python3
  
  import sys
  from http.server import HTTPServer, SimpleHTTPRequestHandler, test
  
  class CORSRequestHandler (SimpleHTTPRequestHandler):
      def end_headers (self):
          self.send_header(&quot;Cross-Origin-Embedder-Policy&quot;, &quot;require-corp&quot;)
          self.send_header(&quot;Cross-Origin-Opener-Policy&quot;, &quot;same-origin&quot;)
  
          SimpleHTTPRequestHandler.end_headers(self)
  
  
  if __name__ == '__main__':
      Handler = CORSRequestHandler
      Handler.extensions_map[&quot;.js&quot;] = &quot;application/javascript&quot;
      Handler.extensions_map[&quot;.wasm&quot;] = &quot;application/wasm&quot;
  
      test(Handler, HTTPServer, port=int(sys.argv[1]) if len(sys.argv) &gt; 1 else 8000)
  </code></pre>
  <p>However, when I navigate to <code>http://localhost:8000/ExampleTests.html</code>, I see a series of errors in the console.</p>
  <pre><code>ExampleTests.worker.js:105 Refused to execute script from 'http://localhost:8000/ExampleTests.js' because its MIME type ('application/wasm') is not executable.
  worker.js onmessage() captured an uncaught exception: NetworkError: Failed to execute 'importScripts' on 'WorkerGlobalScope': The script at 'http://localhost:8000/ExampleTests.js' failed to load.```
  </code></pre>
  <p>Here's the failing function, <code>onmessage()</code>, from <code>ExampleTests.worker.js</code>:</p>
  <pre class="lang-js prettyprint-override"><code>self.onmessage = function(e) {
    try {
      if (e.data.cmd === 'load') { // Preload command that is called once per worker to parse and load the Emscripten code.
  
        // Module and memory were sent from main thread
        Module['wasmModule'] = e.data.wasmModule;
  
        Module['wasmMemory'] = e.data.wasmMemory;
  
        Module['buffer'] = Module['wasmMemory'].buffer;
  
        Module['ENVIRONMENT_IS_PTHREAD'] = true;
  
        if (typeof e.data.urlOrBlob === 'string') {
          console.log(e);
          console.log(e.data);
          console.log(e.data.urlOrBlob);
          importScripts(e.data.urlOrBlob);
        } else {
          var objectUrl = URL.createObjectURL(e.data.urlOrBlob);
          importScripts(objectUrl);
          URL.revokeObjectURL(objectUrl);
        }
      } else if (e.data.cmd === 'run') {
        // This worker was idle, and now should start executing its pthread entry
        // point.
        // performance.now() is specced to return a wallclock time in msecs since
        // that Web Worker/main thread launched. However for pthreads this can
        // cause subtle problems in emscripten_get_now() as this essentially
        // would measure time from pthread_create(), meaning that the clocks
        // between each threads would be wildly out of sync. Therefore sync all
        // pthreads to the clock on the main browser thread, so that different
        // threads see a somewhat coherent clock across each of them
        // (+/- 0.1msecs in testing).
        Module['__performance_now_clock_drift'] = performance.now() - e.data.time;
  
        // Pass the thread address inside the asm.js scope to store it for fast access that avoids the need for a FFI out.
        Module['__emscripten_thread_init'](e.data.threadInfoStruct, /*isMainBrowserThread=*/0, /*isMainRuntimeThread=*/0);
  
        // Establish the stack frame for this thread in global scope
        // The stack grows downwards
        var max = e.data.stackBase;
        var top = e.data.stackBase + e.data.stackSize;
        assert(e.data.threadInfoStruct);
        assert(top != 0);
        assert(max != 0);
        assert(top &gt; max);
        // Also call inside JS module to set up the stack frame for this pthread in JS module scope
        Module['establishStackSpace'](top, max);
        Module['PThread'].receiveObjectTransfer(e.data);
        Module['PThread'].threadInit();
  
        // Embind must initialize itself on all threads, as it generates support JS.
        // We only do this once per worker since they get reused
        if (!initializedJS) {
          Module['___embind_register_native_and_builtin_types']();
          initializedJS = true;
        }
  
        try {
          // pthread entry points are always of signature 'void *ThreadMain(void *arg)'
          // Native codebases sometimes spawn threads with other thread entry point signatures,
          // such as void ThreadMain(void *arg), void *ThreadMain(), or void ThreadMain().
          // That is not acceptable per C/C++ specification, but x86 compiler ABI extensions
          // enable that to work. If you find the following line to crash, either change the signature
          // to &quot;proper&quot; void *ThreadMain(void *arg) form, or try linking with the Emscripten linker
          // flag -s EMULATE_FUNCTION_POINTER_CASTS=1 to add in emulation for this x86 ABI extension.
          var result = Module['invokeEntryPoint'](e.data.start_routine, e.data.arg);
  
          Module['checkStackCookie']();
          if (Module['keepRuntimeAlive']()) {
            Module['PThread'].setExitStatus(result);
          } else {
            Module['__emscripten_thread_exit'](result);
          }
        } catch(ex) {
          if (ex != 'unwind') {
            // FIXME(sbc): Figure out if this is still needed or useful.  Its not
            // clear to me how this check could ever fail.  In order to get into
            // this try/catch block at all we have already called bunch of
            // functions on `Module`.. why is this one special?
            if (typeof(Module['_emscripten_futex_wake']) !== 'function') {
              err(&quot;Thread Initialisation failed.&quot;);
              throw ex;
            }
            // ExitStatus not present in MINIMAL_RUNTIME
            if (ex instanceof Module['ExitStatus']) {
              if (Module['keepRuntimeAlive']()) {
                err('Pthread 0x' + Module['_pthread_self']().toString(16) + ' called exit(), staying alive due to noExitRuntime.');
              } else {
                err('Pthread 0x' + Module['_pthread_self']().toString(16) + ' called exit(), calling _emscripten_thread_exit.');
                Module['__emscripten_thread_exit'](ex.status);
              }
            }
            else
            {
              Module['__emscripten_thread_exit'](-2);
              throw ex;
            }
          } else {
            // else e == 'unwind', and we should fall through here and keep the pthread alive for asynchronous events.
            err('Pthread 0x' + Module['_pthread_self']().toString(16) + ' completed its main entry point with an `unwind`, keeping the worker alive for asynchronous operation.');
          }
        }
      } else if (e.data.cmd === 'cancel') { // Main thread is asking for a pthread_cancel() on this thread.
        if (Module['_pthread_self']()) {
          Module['__emscripten_thread_exit'](-1/*PTHREAD_CANCELED*/);
        }
        postMessage({ 'cmd': 'cancelDone' });
      } else if (e.data.target === 'setimmediate') {
        // no-op
      } else if (e.data.cmd === 'processThreadQueue') {
        if (Module['_pthread_self']()) { // If this thread is actually running?
          Module['_emscripten_current_thread_process_queued_calls']();
        }
      } else {
        err('worker.js received unknown command ' + e.data.cmd);
        err(e.data);
      }
    } catch(ex) {
      err('worker.js onmessage() captured an uncaught exception: ' + ex);
      if (ex &amp;&amp; ex.stack) err(ex.stack);
      throw ex;
    }
  };
  </code></pre>
  <p><code>importScripts(e.data.urlOrBlob);</code> is the failing line, so I added some additional console log messages (which you can see in the code snippet). Here's the output of those logs messages:</p>
  <pre><code>MessageEvent {isTrusted: true, data: {…}, origin: '', lastEventId: '', source: null, …}
  bubbles: false
  cancelBubble: false
  cancelable: false
  composed: false
  currentTarget: DedicatedWorkerGlobalScope {name: '', onmessageerror: null, onmessage: ƒ, cancelAnimationFrame: ƒ, close: ƒ, …}
  data: {cmd: 'load', urlOrBlob: 'http://localhost:8000/ExampleTests.js', wasmMemory: Memory(256), wasmModule: Module}
  defaultPrevented: false
  eventPhase: 0
  isTrusted: true
  lastEventId: &quot;&quot;
  origin: &quot;&quot;
  path: []
  ports: []
  returnValue: true
  source: null
  srcElement: DedicatedWorkerGlobalScope {name: '', onmessageerror: null, onmessage: ƒ, cancelAnimationFrame: ƒ, close: ƒ, …}
  target: DedicatedWorkerGlobalScope {name: '', onmessageerror: null, onmessage: ƒ, cancelAnimationFrame: ƒ, close: ƒ, …}
  timeStamp: 0
  type: &quot;message&quot;
  userActivation: null
  [[Prototype]]: MessageEvent
  </code></pre>
  <pre><code>{cmd: 'load', urlOrBlob: 'http://localhost:8000/ExampleTests.js', wasmMemory: Memory(256), wasmModule: Module}
  cmd: &quot;load&quot;
  urlOrBlob: &quot;http://localhost:8000/ExampleTests.js&quot;
  wasmMemory: 
  Memory(256)
  wasmModule: Module {}
  [[Prototype]]: Object
  </code></pre>
  <pre><code>http://localhost:8000/ExampleTests.js
  </code></pre>
  <hr />
  <p>Does anyone know why http://localhost:8000/ExampleTests.js is failing to load?</p>
  <p>Is there any additional information that would be helpful for debugging?</p>