Skip to content

placeholder shortcode fails on all non-SVG output: svg2png.deno.dev sunset (404) #14722

Description

@cderv

The built-in placeholder shortcode renders a PNG by fetching from https://svg2png.deno.dev/. That service ran on Deno Deploy Classic, which was sunset on 2026-07-20, and now returns a permanent 404:

404 Not Found — The requested deployment does not exist. Deno Deploy Classic was sunset on July 20, 2026 and no longer serves deployments.

For every output format except Typst (which uses an inline SVG data URI), the fetch fails and the shortcode raises Error rendering placeholder, which aborts the whole render:

local pcallresult, mt, contents = pcall(function()
local mt, contents = pandoc.mediabag.fetch("https://svg2png.deno.dev/" .. svg64)
return mt, contents
end)
if not pcallresult then
error("Error rendering placeholder")
error(contents)
return pandoc.Str("Error rendering placeholder")
end
if mt ~= "image/png" then
error("Expected image/png but got " .. mt)
error(contents)
return pandoc.Str("Error rendering placeholder")
end

I can reproduce on both html and pdf with a minimal document:

![]({{< placeholder 300 200 >}})
ERROR (.../placeholder/placeholder.lua:33) Error rendering placeholder
ERROR (.../placeholder/placeholder.lua:34) nil

On pdf the raised string then leaks into the LaTeX source as an image path, so compilation fails looking for Error rendering placeholder.pdf. The svg path (Typst, or an explicit format=svg) still works because it never touches the network.

This also breaks CI: the smoke-all test tests/docs/smoke-all/2026/02/04/issue-13992-figure.qmd renders a placeholder to PDF and now fails.

We could:

  1. render the PNG locally so there is no network dependency,
  2. host an equivalent svg-to-png endpoint under Quarto's control, or
  3. emit the inline SVG data URI for all formats, not just Typst.

Separately, the error handling at lines 33-35 has dead code: error() raises immediately, so the second error(contents) and the pandoc.Str("Error rendering placeholder") return are never reached, and the raised message is what ends up used as the image path.

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingshortcodesissues related to shortcodes

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions