siyuan-note/siyuan · error
HTML to Markdown panicked: %v
Error message
HTML to Markdown panicked: %v
What it means
This is the panic-derived error constructed inside safeHTML2Markdown (webfetch.go:122-127). engine.HTML2Markdown panicked and the deferred recover() caught it, converting the runtime panic value into fmt.Errorf("HTML to Markdown panicked: %v", r). It surfaces as the inner cause wrapped by error 1186. It signals an internal parser/stack fault, not a routine parse error.
Source
Thrown at kernel/util/webfetch.go:125
default: // markdown
md, mdErr := safeHTML2Markdown(engine, htmlStr)
if mdErr != nil {
return "", errors.New("HTML to Markdown conversion failed: " + mdErr.Error())
}
result = md
}
if result == "" {
return htmlStr, nil
}
return truncateRunes(result, maxWebFetchChars), nil
}
func safeHTML2Markdown(engine *lute.Lute, htmlStr string) (result string, err error) {
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("HTML to Markdown panicked: %v", r)
}
}()
result, err = engine.HTML2Markdown(htmlStr)
return
}
func safeHTML2Text(engine *lute.Lute, htmlStr string) (result string, err error) {
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("HTML to text panicked: %v", r)
}
}()
result = engine.HTML2Text(htmlStr)
return
}
func truncateRunes(s string, maxChars int) string {
runes := []rune(s)View on GitHub (pinned to 251596fc0d)
Solutions
- Switch to format="text" (safeHTML2Text) or accept the raw HTML fallback path.
- Upgrade lute from 88250/lute and rebuild — panic fixes land upstream.
- Binary-search the input to find the minimal HTML fragment that triggers the panic and report it upstream with that sample.
- Because truncation happens AFTER conversion, pre-truncating huge HTML before calling may avoid stack blow-up.
Defensive patterns
Strategy: fallback
Type guard
func isHTML2MarkdownPanic(err error) bool {
return err != nil && strings.HasPrefix(err.Error(), "HTML to Markdown panicked:")
} Try / catch
// safeHTML2Markdown already recovers the panic, so the caller sees an error,
// not a crash. Fall back to text or raw HTML.
out, err := util.WebFetch(raw, "markdown")
if err != nil && isHTML2MarkdownPanic(err) {
out, err = util.WebFetch(raw, "text")
} Prevention
- Treat any panic-derived error as a lute bug to report upstream with a reduced HTML sample.
- Pre-truncate huge HTML before converting — truncation currently happens only AFTER conversion.
- Keep lute upgraded; parser panic fixes land in 88250/lute.
When it happens
Trigger: Stack overflow from pathological DOM nesting, nil-pointer dereference inside lute on unexpected input, recursive grammar blow-up, or an invariant violation in lute's AST handling.
Common situations: Adversarial/hand-crafted HTML, very large deeply nested tables, pages engineered to stress parsers, a lute version regression.
Related errors
- HTML to text panicked: %v
- parse tree [%s] failed
- parse font failed: %v
- HTML to Markdown conversion failed: %s
- panic: gulu.Zip.Unzip error (dynamic message from err)
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/44e6463079423a08.
Report an issue: GitHub.