{"record":{"id":"eaba7be4bdcac313","repo":"siyuan-note/siyuan","slug":"347","errorCode":"347","errorMessage":"parse Markdown [%s] failed","messagePattern":"parse Markdown \\[(.+?)\\] failed","errorType":"error_code","errorClass":"obsidianUserError","httpStatus":null,"severity":"error","filePath":"kernel/model/import_obsidian.go","lineNumber":876,"sourceCode":"\t\t\treturn newObsidianReadUserError(doc.Source, err)\n\t\t}\n\t\tif !utf8.Valid(data) {\n\t\t\treturn newObsidianUserError(344, doc.Source.RelPath,\n\t\t\t\tfmt.Errorf(\"Markdown [%s] is not valid UTF-8\", doc.Source.RelPath))\n\t\t}\n\t\tscan := scanObsidianSource(data)\n\t\tfor _, blockID := range scan.BlockIDs {\n\t\t\tif scan.Duplicates[blockID] {\n\t\t\t\tdoc.DuplicateBlocks[blockID] = true\n\t\t\t}\n\t\t\tif doc.BlockIDs[blockID] == \"\" {\n\t\t\t\tdoc.BlockIDs[blockID] = ast.NewNodeID()\n\t\t\t}\n\t\t}\n\t\ttree, _, _, _ := parseStdMd(data)\n\t\tif tree == nil {\n\t\t\treturn newObsidianUserError(347, doc.Source.RelPath,\n\t\t\t\tfmt.Errorf(\"parse Markdown [%s] failed\", doc.Source.RelPath))\n\t\t}\n\t\tbuildObsidianHeadingIndex(doc, tree)\n\t\tvault.Analysis.WikiLinkCount += countObsidianNonEmbedTokens(scan.Wikis)\n\t\tvault.Analysis.EmbedCount += countObsidianEmbedTokens(scan.Wikis)\n\t\tvault.Analysis.CommentCount += len(scan.Comments)\n\t\tvault.Analysis.FootnoteCount += scan.Footnotes\n\t\tvault.Analysis.BlockIDCount += len(scan.BlockIDs)\n\t\tprocessed++\n\t\tprogress(35+processed*30/maxInt(sourceCount, 1), \"Analyzing Markdown syntax\")\n\t}\n\n\tfor _, doc := range vault.Docs {\n\t\tif doc.Synthetic {\n\t\t\tcontinue\n\t\t}\n\t\tif err := ctx.Err(); err != nil {\n\t\t\treturn err\n\t\t}","sourceCodeStart":858,"sourceCodeEnd":894,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/kernel/model/import_obsidian.go#L858-L894","documentation":"First analysis pass: parseStdMd(data) returned a nil parse.Tree for a markdown file. Reported with language code 347 ('Unable to convert Markdown file [%s]'). parseStdMd parses the file as standard (non-SiYuan) Markdown via Lute; a nil tree means Lute rejected the input outright rather than producing a partial AST. This blocks heading/block-ID indexing for that file.","triggerScenarios":"Severe Markdown corruption that defeats the parser: file containing mostly binary/null bytes that nonetheless passed UTF-8 validation, extremely deep nesting exceeding parser limits, or a Lute internal panic recovered into a nil tree. Rare in practice because most malformed Markdown still yields a permissive AST.","commonSituations":"A .md file that is UTF-8 but structurally pathological (megabytes of unclosed brackets/fences, deeply nested blockquote/list stacks); a file that is actually a different format renamed to .md; a Lute version regression that fails on a specific construct.","solutions":["Open the reported file in a Markdown linter/editor and fix or simplify the offending construct (unclosed code fences, runaway nesting).","If the file is not real Markdown, rename it to a non-.md extension or move it out of the vault.","Trim/truncate an absurdly large single file and retry analysis; if it then parses, narrow down the offending region.","Check the kernel log for the underlying Lute error/stack to identify the exact construct, then file a Lute issue with a minimal reproducer."],"exampleFix":"// before: file with an unterminated code fence spanning the whole doc\n//   ```python\n//   ... 10MB of content with no closing fence\n\n// after: close the fence (or split the file)\n//   ```python\n//   ...\n//   ```","handlingStrategy":"validation","validationCode":"// Pre-parse each markdown with a lenient parser/linter to catch hard failures.\nfunc vaultMarkdownParses(root string) (string, error) {\n    var first string\n    err := filepath.WalkDir(root, func(p string, d fs.DirEntry, err error) error {\n        if err != nil || d.IsDir() || !strings.HasSuffix(p, \".md\") { return err }\n        b, e := os.ReadFile(p); if e != nil { return e }\n        if _, e := parseStdMd(b); e != nil || treeIsNil { first = p; return errors.New(\"unparseable\") }\n        return nil\n    })\n    return first, err\n}","typeGuard":"null","tryCatchPattern":"null","preventionTips":["Lint vault markdown (markdownlint / mdformat) before import.","Close all code fences and blockquotes; avoid runaway nesting.","Keep files to reasonable sizes to avoid parser edge cases."],"tags":["obsidian-import","markdown","parser","lute"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}