siyuan-note/siyuan · error
svg contains multiple root elements
Error message
svg contains multiple root elements
What it means
After the root <svg> element has been closed (rootClosed), any further StartElement token triggers this error. Well-formed XML allows exactly one root element, so a second top-level element means the input is a document fragment, concatenated SVGs, or has stray content after the root. The sanitizer enforces single-root XML semantics to keep output a valid standalone SVG.
Source
Thrown at kernel/util/misc.go:373
break
}
if err != nil {
return "", fmt.Errorf("parse svg failed: %w", err)
}
tokenCount++
if tokenCount > maxSVGTokens {
return "", fmt.Errorf("svg contains too many tokens")
}
switch typed := token.(type) {
case xml.StartElement:
elementStack = append(elementStack, typed.Name)
depth++
if depth > maxSVGDepth {
return "", fmt.Errorf("svg nesting depth exceeds %d", maxSVGDepth)
}
if rootClosed {
return "", fmt.Errorf("svg contains multiple root elements")
}
if !rootSeen {
if !strings.EqualFold(typed.Name.Local, "svg") {
return "", fmt.Errorf("root element is not svg")
}
rootSeen = true
}
if skipDepth > 0 {
skipDepth++
continue
}
if _, unsafe := unsafeSVGElements[strings.ToLower(typed.Name.Local)]; unsafe {
skipDepth = 1
continue
}
typed.Name = preserveXMLName(typed.Name)View on GitHub (pinned to 8641553a1f)
Solutions
- Ensure the input contains exactly one root <svg> element — split multiple icons into separate files/calls
- Strip any content (text, comments-producing artifacts, extra elements) after the closing </svg>
- Fix the template/packaging step that concatenates SVG documents; wrap multiple icons in distinct sanitized calls
- If a sprite is needed, place icons as <symbol> children inside a single root <svg> instead of sibling roots
Example fix
// before combined := svg1 + svg2 // two root elements out, err := util.SanitizeSVG(combined) // after out1, err1 := util.SanitizeSVG(svg1) out2, err2 := util.SanitizeSVG(svg2) // sanitize each document separately
Defensive patterns
Strategy: validation
Validate before calling
if strings.Count(strings.TrimSpace(svg), "</svg>") > 1 { return errors.New("multiple root elements; split into separate SVG documents") } Try / catch
out, err := util.SanitizeSVG(svg)
if err != nil && strings.Contains(err.Error(), "multiple root elements") {
// split the input on '</svg>' boundaries and sanitize each part
} Prevention
- Ensure each file/paste contains exactly one <svg> root
- Strip trailing junk after </svg> before sanitizing
- For icon sets, use <symbol> children inside one root instead of sibling roots
- Fix build/packaging scripts that concatenate SVG documents
When it happens
Trigger: Passing content to SanitizeSVG that contains two sibling top-level elements — e.g. '<svg>...</svg><svg>...</svg>', 'text after </svg>', an SVG pasted twice, or template concatenation of multiple icon files.
Common situations: Batch-exported icon sets concatenated into one file, copy/paste that grabbed two icons, HTML snippets where multiple inline SVGs were joined, or a build step appending trailing content after the closing tag.
Related errors
- parse svg failed: %w
- svg contains too many tokens
- svg nesting depth exceeds %d
- root element is not svg
- svg contains text outside the root element
AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11).
Data as JSON: /api/errors/ababb5d3bc4dc006.
Report an issue: GitHub.