d2lang/d2 · error
native Markdown SVG does not support HTML element <%s>
Error message
native Markdown SVG does not support HTML element <%s>
What it means
D2's native (wasm/browser) Markdown-to-SVG renderer walks the parsed HTML tree of Markdown output and only knows how to render a whitelist of block/inline elements. When validateMarkdownSVGNodes encounters any other element name it returns this error. The native renderer is a limited subset of the full JS DOM-based markdown renderer.
Source
Thrown at lib/textmeasure/markdown_svg.go:1923
func nodeAttr(n *html.Node, name string) string {
for _, attr := range n.Attr {
if attr.Key == name {
return attr.Val
}
}
return ""
}
func validateMarkdownSVGNodes(n *html.Node) error {
if n.Type == html.ElementNode {
switch n.Data {
case "html", "head", "body",
"p", "h1", "h2", "h3", "h4", "h5", "h6",
"blockquote", "ul", "ol", "li", "pre", "code",
"em", "b", "strong", "del", "s", "strike", "a", "br", "hr", "img",
"table", "thead", "tbody", "tfoot", "tr", "td", "th":
default:
return fmt.Errorf("native Markdown SVG does not support HTML element <%s>", n.Data)
}
}
for child := n.FirstChild; child != nil; child = child.NextSibling {
if err := validateMarkdownSVGNodes(child); err != nil {
return err
}
}
return nil
}
func goMax(a, b float64) float64 {
if a > b {
return a
}
return b
}
// textBaseline matches CSS line-box placement: half of the extra line-heightView on GitHub (pinned to 0d69dca6f5)
Solutions
- Remove or replace the unsupported HTML element from the Markdown source
- Render with the non-native (JS/hosted) markdown renderer which supports full HTML
- Escape the HTML so it renders as literal text instead of being parsed as an element
- Upgrade d2 to a newer version in case the supported element list has expanded
Example fix
// before diagram += "<details><summary>Notes</summary>...</details>" // after diagram += "**Notes** (details not supported in native SVG)"
Defensive patterns
Strategy: validation
Validate before calling
var allowed = map[string]bool{"html":true,"p":true,"h1":true,"h2":true,"h3":true,"h4":true,"h5":true,"h6":true,"blockquote":true,"ul":true,"ol":true,"li":true,"pre":true,"code":true,"em":true,"b":true,"strong":true,"del":true,"s":true,"strike":true,"a":true,"br":true,"hr":true,"img":true,"table":true,"thead":true,"tbody":true,"tfoot":true,"tr":true,"td":true,"th":true}
// pre-scan markdown HTML nodes; reject/sanitize unsupported tags before rendering Type guard
func isSupportedHTMLElement(tag string) bool {
return allowed[tag]
} Try / catch
svg, err := RenderMarkdownSVG(md)
if err != nil {
if strings.Contains(err.Error(), "does not support HTML element") {
return renderFallback(md) // or strip HTML and retry
}
return err
} Prevention
- Restrict Markdown input to plain Markdown syntax, not raw HTML
- Sanitize/strip unsupported HTML tags from user descriptions before rendering
- Test rendering in the native (wasm) target, not just the hosted renderer
- Pin d2 versions and review the supported element list when upgrading
When it happens
Trigger: Rendering a Markdown diagram to SVG in the WASM/native runtime while the markdown contains HTML elements outside the supported list — e.g. <video>, <audio>, <details>, <summary>, <sup>, <sub>, <iframe>, <button>, custom tags, or raw HTML pasted into the diagram description.
Common situations: Users pasting rich HTML into Markdown descriptions; markdown extensions (like footnote or collapsible sections) emitting elements the native renderer doesn't implement; differences between native and hosted rendering behavior.
Related errors
- response.error.message
- response.error.message
- code snippet style "github" not found
- code snippet formatter "svg" not found
- padding %d produces invalid SVG dimensions
AI-assisted analysis of d2lang/d2@0d69dca6f5 (2026-08-31).
Data as JSON: /api/errors/7c2bce338b69047c.
Report an issue: GitHub.