A language's parser could not be loaded.
Lumis.highlight/2 returns this when the root language of a document is
unavailable. An injected language is not an error — that block stays plain
and the rest of the document still highlights.
Match on :reason rather than on the message:
case Lumis.highlight(source, formatter: {:html_inline, language: "elixir"}) do
{:ok, html} ->
html
{:error, %Lumis.ParserError{reason: :not_installed, package: package}} ->
Logger.error("add {:#{package}, \"~> 0.26\"} to mix.exs")
Plug.HTML.html_escape(source)
{:error, error} ->
Logger.error(Exception.message(error))
Plug.HTML.html_escape(source)
endReasons
:not_installed— the parser is not a dependency of this project. The only reason a deployment normally sees, and the only one adding a dependency fixes.:parser_missing— it is a dependency, but the.wasmits manifest names is not beside it. Fetching dependencies again is the fix; adding the dependency is not, since it is already there.:unknown_language— the name is not in the catalog:not_loaded— the language is known but no store could supply it:not_cached— its bytes are not on disk and nothing fetched them:incompatible_version— the installed parser package is outside the range this build of Lumis supports;:detailnames both:download_failed,:unavailable— it is neither installed nor reachable over the network:invalid_package,:invalid_package_name,:package_name_mismatch— the package could not be read, or is not the one that was asked for:invalid_parser,:invalid_queries— the parser WASM or its queries were rejected:io— a read or a write was refused:store_unavailable— this runtime has no language store at all:store_full— the parser is fine and this process has no room for another one. Every language shares one Tree-sitter Wasm store whose memory is capped and never reclaimed, so past a point the next parser does not fit, whatever the machine has free. The language named is not at fault: it loads on its own, and which languages fail depends only on the order they were asked for. Nothing the running VM can do recovers — loading is global to it and no parser is ever unloaded — so this is a decision about which languages a boot loads, and work that needs more than fit has to be split across OS processes, the cap being per process and not per scheduler.
The list is open: a Lumis release can add a reason, so a case over it needs
a catch-all clause.
Fields
:language— the language id that could not be loaded:package— the Hex package that supplies it,nilwhen the language is not in the catalog:reason— one of the atoms above:detail— what the Rust core reported, for logs