siyuan-note/siyuan · error

347

347

Error message

parse Markdown [%s] failed

What it means

parseStdMd failed to produce a parse tree for a Vault Markdown document (error code 347), so the analysis phase aborts for that document. The Lute-based standard-Markdown parser returned nil, which the importer treats as an unrecoverable parse failure rather than continuing with a broken tree.

Solutions

  1. Open the reported file in a Markdown editor and look for unusual syntax; simplify or split it
  2. Bisect the file content (halve it) to find the construct that breaks parsing
  3. Update SiYuan — the bundled lute parser may have fixed the issue in a newer version
  4. If reproducible, report the file snippet as a lute parser bug
Defensive patterns

Strategy: try-catch

Try / catch

try {
  await importObsidianVault(vaultPath);
} catch (e) {
  if (e.code === 347) {
    const file = /Markdown \[([^\]]+)\]/.exec(e.message)?.[1];
    console.error('Simplify or repair:', file);
  }
}

Prevention

When it happens

Trigger: During document analysis, parseStdMd(data) returns tree == nil for doc.Source.RelPath — i.e. the Lute parser rejected the (already UTF-8 validated) content.

Common situations: Pathological or deeply nested Markdown that triggers parser limits; corrupted file content; an upstream lute regression for exotic syntax.

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


AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19). Data as JSON: /api/errors/eaba7be4bdcac313. Report an issue: GitHub.

Appendix: source

Thrown at kernel/model/import_obsidian.go:876

			return newObsidianReadUserError(doc.Source, err)
		}
		if !utf8.Valid(data) {
			return newObsidianUserError(344, doc.Source.RelPath,
				fmt.Errorf("Markdown [%s] is not valid UTF-8", doc.Source.RelPath))
		}
		scan := scanObsidianSource(data)
		for _, blockID := range scan.BlockIDs {
			if scan.Duplicates[blockID] {
				doc.DuplicateBlocks[blockID] = true
			}
			if doc.BlockIDs[blockID] == "" {
				doc.BlockIDs[blockID] = ast.NewNodeID()
			}
		}
		tree, _, _, _ := parseStdMd(data)
		if tree == nil {
			return newObsidianUserError(347, doc.Source.RelPath,
				fmt.Errorf("parse Markdown [%s] failed", doc.Source.RelPath))
		}
		buildObsidianHeadingIndex(doc, tree)
		vault.Analysis.WikiLinkCount += countObsidianNonEmbedTokens(scan.Wikis)
		vault.Analysis.EmbedCount += countObsidianEmbedTokens(scan.Wikis)
		vault.Analysis.CommentCount += len(scan.Comments)
		vault.Analysis.FootnoteCount += scan.Footnotes
		vault.Analysis.BlockIDCount += len(scan.BlockIDs)
		processed++
		progress(35+processed*30/maxInt(sourceCount, 1), "Analyzing Markdown syntax")
	}

	for _, doc := range vault.Docs {
		if doc.Synthetic {
			continue
		}
		if err := ctx.Err(); err != nil {
			return err
		}

View on GitHub (pinned to 9f775e8a12)