siyuan-note/siyuan · error
svg contains text outside the root element
Error message
svg contains text outside the root element
What it means
Non-whitespace character data was found either before the root element opened or after it closed. Valid standalone SVG allows text only inside the <svg> root; stray text around it (or between multiple documents) is rejected both because it is not a valid SVG image and as an anti-smuggling measure.
Source
Thrown at kernel/util/misc.go:426
if depth == 0 {
rootClosed = true
}
continue
}
typed.Name = preserveXMLName(typed.Name)
if err = encoder.EncodeToken(typed); err != nil {
return "", fmt.Errorf("render svg failed: %w", err)
}
depth--
if depth == 0 {
rootClosed = true
}
case xml.CharData:
if skipDepth > 0 {
continue
}
if (!rootSeen || rootClosed) && strings.TrimSpace(string(typed)) != "" {
return "", fmt.Errorf("svg contains text outside the root element")
}
if rootSeen && !rootClosed {
if err = encoder.EncodeToken(typed); err != nil {
return "", fmt.Errorf("render svg failed: %w", err)
}
}
case xml.Comment:
if skipDepth == 0 && rootSeen && !rootClosed {
if err = encoder.EncodeToken(typed); err != nil {
return "", fmt.Errorf("render svg failed: %w", err)
}
}
case xml.Directive:
if !isBenignSVGDoctype(string(typed)) {
return "", fmt.Errorf("svg directives are not allowed")
}
// 良性 DOCTYPE 声明不写入输出,与 XML 声明(ProcInst)的处理方式一致,不影响浏览器渲染
case xml.ProcInst:View on GitHub (pinned to 8641553a1f)
Solutions
- Delete the non-whitespace text outside the <svg>...</svg> range before sanitizing
- Extract just the svg element (regex or string slicing on the first '<svg' and last '</svg>') when accepting arbitrary pastes
- Do not concatenate multiple SVG documents; use <svg> with multiple children or an <symbol>/<use> structure instead
- Trim input and check that it starts with '<svg' or an allowed prolog (xml decl, comment, DOCTYPE)
Example fix
// before
SanitizeSVG("icon: <svg>...</svg>") // text outside the root element
// after
SanitizeSVG("<svg xmlns=\"http://www.w3.org/2000/svg\">...</svg>") Defensive patterns
Strategy: validation
Validate before calling
func extractSVGDoc(input string) (string, bool) {
start := strings.Index(input, "<svg")
end := strings.LastIndex(input, "</svg>")
if start < 0 || end < 0 || end <= start { return "", false }
return input[start : end+len("</svg>")], true
} Try / catch
doc, ok := extractSVGDoc(userInput)
if !ok { return errors.New("no complete svg element found in input") }
clean, err := util.SanitizeSVG(doc)
if err != nil { return err } Prevention
- Slice user pastes down to the <svg>...</svg> span before sanitizing
- Reject concatenations of multiple SVG documents
- Trim and inspect surrounding text when accepting clipboard content
- Strip prose/logs accidentally captured with the icon
When it happens
Trigger: 'hello<svg>...</svg>' (text before root), '<svg>...</svg>trailing text', two SVGs concatenated back to back with text in between, or an HTML wrapper with visible text around the svg tag.
Common situations: Pasting an SVG copied from a webpage along with surrounding text; concatenating icon files; log/console text accidentally included in the paste.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- root element is not svg
- svg contains an unexpected closing element
- svg closing element %q does not match %q
- svg directives are not allowed
- svg root element is incomplete
AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11).
Data as JSON: /api/errors/83a08a44cb00c026.
Report an issue: GitHub.