siyuan-note/siyuan · error
HTML to text panicked: %v
Error message
HTML to text panicked: %v
What it means
The panic-derived error from safeHTML2Text (webfetch.go:132-138). engine.HTML2Text panicked and the deferred recover() caught it, becoming fmt.Errorf("HTML to text panicked: %v", r). Note safeHTML2Text's err return value is currently discarded at the call site (webfetch.go:106: `result, _ = safeHTML2Text(...)`) so this specific error string is not propagated to the caller — a panic here silently yields an empty result, which then falls through to the raw HTML fallback at webfetch.go:115-117.
Source
Thrown at kernel/util/webfetch.go:135
}
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)
if len(runes) <= maxChars {
return s
}
return string(runes[:maxChars]) + "\n\n...content truncated, total length " + fmt.Sprintf("%d", len(runes)) + " characters..."
}
func extractFilename(rawURL, contentType string) string {
u, err := url.Parse(rawURL)
if err != nil {
return gulu.Rand.String(7) + extByContentType(contentType)View on GitHub (pinned to 251596fc0d)
Solutions
- Rely on the automatic raw-HTML fallback (result=="" returns htmlStr unchanged) — the user still gets content.
- Upgrade lute and rebuild.
- Reduce the input to a minimal reproducer and report to 88250/lute.
- If you need the error surfaced, capture it at the call site instead of discarding with `_`.
Example fix
// before (webfetch.go:106): error discarded
result, _ = safeHTML2Text(engine, htmlStr)
// after: surface the text-path error for diagnostics
result, txtErr := safeHTML2Text(engine, htmlStr)
if txtErr != nil {
logging.LogErrorf("html2text failed: %s", txtErr)
} Defensive patterns
Strategy: fallback
Type guard
func isHTML2TextPanic(err error) bool {
return err != nil && strings.HasPrefix(err.Error(), "HTML to text panicked:")
} Try / catch
// NOTE: at webfetch.go:106 the text-path error is discarded (`result, _ = ...`),
// so callers never see this string today — a panic here silently yields the
// raw-HTML fallback. If you surface the error, handle it as a non-fatal fallback.
out, err := util.WebFetch(raw, "text")
if err != nil {
// fall back to the raw HTML returned on the empty-result branch
} Prevention
- Remember the text path's error is currently discarded — rely on the raw-HTML fallback rather than expecting this error externally.
- Upgrade lute to pick up HTML2Text panic fixes.
- Reduce the triggering HTML and report it to 88250/lute.
When it happens
Trigger: Same class as 1187 but on the text-extraction path (format="text"): pathological nesting, obfuscated HTML, lute internal fault.
Common situations: Choosing format="text" to dodge a Markdown-conversion panic, only to hit a different lute panic; lute version regression.
Related errors
- HTML to Markdown panicked: %v
- parse tree [%s] failed
- parse font failed: %v
- HTML to Markdown conversion failed: %s
- text value is missing
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/99f259849840d4e7.
Report an issue: GitHub.