{"record":{"id":"7b577c767d450162","repo":"siyuan-note/siyuan","slug":"html-to-markdown-conversion-failed-s","errorCode":null,"errorMessage":"HTML to Markdown conversion failed: %s","messagePattern":"HTML to Markdown conversion failed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/util/webfetch.go","lineNumber":109,"sourceCode":"\n\tisHTML := strings.HasPrefix(contentType, \"text/html\")\n\tif !isHTML {\n\t\treturn truncateRunes(htmlStr, maxWebFetchChars), nil\n\t}\n\n\tif htmlStr == \"\" {\n\t\treturn \"\", nil\n\t}\n\n\tengine := NewLute()\n\tvar result string\n\tswitch format {\n\tcase \"text\":\n\t\tresult, _ = safeHTML2Text(engine, htmlStr)\n\tdefault: // markdown\n\t\tmd, mdErr := safeHTML2Markdown(engine, htmlStr)\n\t\tif mdErr != nil {\n\t\t\treturn \"\", errors.New(\"HTML to Markdown conversion failed: \" + mdErr.Error())\n\t\t}\n\t\tresult = md\n\t}\n\n\tif result == \"\" {\n\t\treturn htmlStr, nil\n\t}\n\n\treturn truncateRunes(result, maxWebFetchChars), nil\n}\n\nfunc safeHTML2Markdown(engine *lute.Lute, htmlStr string) (result string, err error) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\terr = fmt.Errorf(\"HTML to Markdown panicked: %v\", r)\n\t\t}\n\t}()\n\tresult, err = engine.HTML2Markdown(htmlStr)","sourceCodeStart":91,"sourceCodeEnd":127,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/util/webfetch.go#L91-L127","documentation":"When format is 'markdown' (the default), WebFetch converts the fetched HTML with lute's HTML2Markdown via the panic-protected safeHTML2Markdown wrapper; a non-nil conversion error is wrapped as 'HTML to Markdown conversion failed: <cause>'. This indicates the Lute engine rejected or failed on the specific HTML content, not a network problem.","triggerScenarios":"engine.HTML2Markdown returns an error for pathological or malformed HTML (deeply nested structures, encoding oddities, input the converter cannot process).","commonSituations":"Fetching pages with heavily malformed tag soup; documents with exotic encodings that survived the fetch as invalid UTF-8; upstream Lute version changes altering conversion behavior on edge-case markup.","solutions":["Retry with format=\"text\" which uses safeHTML2Text and never returns a conversion error","Inspect the wrapped cause after 'HTML to Markdown conversion failed: ' for the specific Lute failure","Sanitize or simplify the HTML upstream if you control the source page","Check the Lute version if the same URL previously converted fine — behavior may have changed upstream"],"exampleFix":"// before\nmd, err := WebFetch(url, \"markdown\") // conversion fails on malformed HTML\n\n// after\ntext, err := WebFetch(url, \"text\") // fall back to plain-text extraction\nif err == nil {\n    md = text\n}","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"md, err := WebFetch(url, \"markdown\")\nif err != nil && strings.Contains(err.Error(), \"conversion failed\") {\n    md, err = WebFetch(url, \"text\") // text path has no conversion error return\n}","preventionTips":["Prefer pages with reasonably well-formed HTML for Markdown conversion","Fall back to format=\"text\" when conversion fails","Pin and test the Lute version when upgrading — conversion behavior changes","Log the failing URL so pathological sources can be sanitized or blacklisted"],"tags":["markdown","html","conversion","lute"],"backgroundTag":"html-parse-error","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}