Common Problems and Fixes in quarto-webR


March 20, 2023


June 16, 2024

As this is an exciting new frontier, we’re learning as we go. Or as my friend Lawrence says, “I like to build airplanes in the air-”. In the spirit of learning, let’s address some common issues you may come across…

Stuck at Loading webR…

Problem: If you encounter the message Loading webR... above your code cell instead of Run code, it’s likely due to missing worker files (webr-worker.js and webr-serviceworker.js) in the document’s root or a relative directory.

Solution: To resolve this issue, make sure that these worker files are located in the same directory as your Quarto document. Here’s the recommended directory structure:

├── demo-quarto-webr.qmd
├── webr-serviceworker.js
└── webr-worker.js

If you still encounter the error after confirming the file placement, check the output of the preview command in either the Terminal or RStudio’s Background Jobs tab. The output might resemble the following:

quarto preview --no-browser --no-watch-inputs

Watching files for changes 
GET: /website/posts/index.html
 /website/posts/webr-serviceworker.js (404: Not Found)
 /website/posts/webr-worker.js (404: Not Found)

This indicates that the webr-serviceworker.js and webr-worker.js files are missing during the rendering stage of your document. To fix this, add the resources key to your document header, explicitly specifying these two JavaScript files like so:

title: "My Post"
  - webr-serviceworker.js
  - webr-worker.js
  - webr

We’ve informed the Quarto team about this issue regarding automatic inclusion of extension registered dependencies.

If the problem persists, you can specify the location of the worker files using the service-worker-url option in the document’s YAML header or set the channel-type option to "post-message". You can see an example of the later here.

Unable to Render the Quarto File

Problem: When I add the webr value to the filter section, my Quarto document fails to render and displays a lengthy error message.

Solution: Quarto extensions are project-specific, which means you must install the extension for each new project you create. To resolve this issue, ensure that your project directory structure includes an _extensions directory with the appropriate extension files, as shown below:

├── _extensions
   └── coatless
       └── webr
           ├── _extension.yml
           ├── ...
           └── webr.lua
└── test-document.qmd

If your directory is missing the _extensions/ folder, please install the webr extension by following the instructions in Install the quarto-webr extension video.

Starting from Quarto v1.4, you will receive an improved error message that emphasizes the extension’s absence from your current working directory.

Missing extension error for Quarto v1.4 and later
FATAL (/Applications/quarto/share/filters/main.lua:129) An error occurred:
Could not run /Users/jjb/github/demo-webr/webr as a JSON filter.
Please make sure the file exists and is executable.

Did you intend 'webr' as a Lua filter in an extension?
If so, make sure you've spelled the name of the extension correctly.

The original Pandoc error follows below.
Error running filter /Users/jjb/github/demo-webr/webr:
Could not find executable /Users/jjb/github/demo-webr/webr

In versions prior to Quarto v1.4, including v1.3 and earlier, the error message may differ, but it typically signals that the extension is either missing or not executable.

Missing extension error for Quarto v1.3 and earlier
Error running filter /Applications/quarto/share/filters/main.lua:
Error running filter /Users/jjb/github/demo-webr/webr:
Could not find executable /Users/jjb/github/demo-webr/webr
stack traceback:
        /Applications/quarto/share/filters/main.lua:4030: in function </Applications/quarto/share/filters/main.lua:4009>
        [C]: in ?
        [C]: in method 'walk'
        /Applications/quarto/share/filters/main.lua:171: in function 'run_emulated_filter'
        /Applications/quarto/share/filters/main.lua:449: in local 'callback'
        /Applications/quarto/share/filters/main.lua:454: in upvalue 'run_emulated_filter_chain'
        /Applications/quarto/share/filters/main.lua:495: in function </Applications/quarto/share/filters/main.lua:476>
stack traceback:
        /Applications/quarto/share/filters/main.lua:171: in function 'run_emulated_filter'
        /Applications/quarto/share/filters/main.lua:449: in local 'callback'
        /Applications/quarto/share/filters/main.lua:454: in upvalue 'run_emulated_filter_chain'
        /Applications/quarto/share/filters/main.lua:495: in function </Applications/quarto/share/filters/main.lua:476>

Directly Accessing Rendered HTML

Problem: When I directly open the rendered HTML document in a web browser, webR components are not loaded due to security reasons.

Solution: When you use quarto preview or quarto render, the rendered HTML document is served by mimicking a server running under https://localhost/. In this context, everything usually works fine if you follow the directory structure mentioned above.

However, if you directly open the rendered HTML document (e.g., demo-quarto-web.html) in a web browser, you may encounter issues with WebR components not loading due to security restrictions. This behavior is explained further in this StackOverflow answer.

To address this problem and avoid the need for a local Quarto installation to open the rendered file directly, you have a few options:

  1. Use Chrome’s --allow-file-access-from-files access: You can modify your Chrome shortcut to include the --allow-file-access-from-files flag. This allows local files to access other local files, potentially resolving the issue.

  2. Use the WebServer for Chrome Extension: Install the WebServer for Chrome extension to serve your HTML files. This extension sets up a local web server that doesn’t have the same security restrictions as directly opening files.

  3. Use NPM to Obtain local-web-server: Install the local-web-server package from npm, which is a lightweight, no-configuration-required HTTP server. You can use it to serve your HTML files without encountering security restrictions.

Speed Up webR

Problem: WebR documents are not performing as efficiently as expected.

Solution: To optimize the performance of webR documents, it’s essential to set appropriate HTTP headers for COOP and COEP. These headers help speed up the process and ensure a smoother user experience.

Here are the recommended COOP and COEP headers to use:

Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp

By configuring these headers, you enforce a same-origin policy for cross-origin windows and ensure that cross-origin iframes are required to have a COEP policy that allows cross-origin embedding. For more detailed instructions on setting up these headers, please refer to the "shared-array-buffer" channel type documentation.

Engine Registration

Problem: When using the knitr engine instead of the jupyter engine and the original tag {webr} instead of {webr-r}, a warning message may appear in the render processing output:

Warning message:
In get_engine(options$engine) :
  Unknown language engine 'webr' (must be registered via knit_engines$set()).

Solution: The warning message about the unknown language engine ‘webr’ is purely cosmetic and does not affect the functionality of the webr filter. It is merely an aesthetic issue and does not impact the execution of code cells.

This warning occurs because the knitr engine is not initially aware of the webr engine. However, this lack of awareness does not cause any functional problems. The webr filter will operate as expected despite this warning.

While the warning is not critical, it may be addressed in future updates for aesthetic reasons. Nevertheless, you can safely disregard this warning message as it does not interfere with the functionality of your webR documents.