siyuan-note/siyuan · error
generated tree [%s] is not valid JSON
Error message
generated tree [%s] is not valid JSON
What it means
writeObsidianTempTree renders the staged parse tree with NewJSONRenderer and then verifies the output with json.Valid. If the rendered bytes are not valid JSON, the generated .sy document would be corrupt, so staging aborts and reports which document tree (by hpath) failed.
Source
Thrown at kernel/model/import_obsidian.go:2350
tree.Root.SetIALAttr("title", doc.Title)
tree.Root.SetIALAttr("updated", util.TimeFromID(doc.ID))
tree.Root.RemoveIALAttrsByPrefix("custom-")
}
func writeObsidianTempTree(docsTemp string, tree *parse.Tree) error {
if tree == nil || tree.Root == nil {
return errors.New("cannot stage an empty tree")
}
if tree.Root.FirstChild == nil {
tree.Root.AppendChild(treenode.NewParagraph(""))
}
treenode.UpgradeSpec(tree)
tree.Root.SetIALAttr("type", "doc")
luteEngine := util.NewLute()
renderer := render.NewJSONRenderer(tree, luteEngine.RenderOptions, luteEngine.ParseOptions)
data := renderer.Render()
if !json.Valid(data) {
return fmt.Errorf("generated tree [%s] is not valid JSON", tree.HPath)
}
if !util.UseSingleLineSave {
var buffer bytes.Buffer
if err := json.Indent(&buffer, data, "", "\t"); err != nil {
return err
}
data = buffer.Bytes()
}
target := filepath.Join(docsTemp, filepath.FromSlash(strings.TrimPrefix(tree.Path, "/")))
if err := os.MkdirAll(filepath.Dir(target), 0755); err != nil {
return err
}
return filelock.WriteFile(target, data)
}
func copyStableObsidianFile(source *obsidianSourceFile, destination string) error {
if err := validateObsidianSourceMetadata(source); err != nil {
return errView on GitHub (pinned to 8641553a1f)
Solutions
- Inspect the source note at the reported hpath for invalid characters or malformed Markdown and sanitize it, then re-import
- Update SiYuan/Lute to the latest version in case of a JSON renderer regression
- Isolate the failing document and import it alone to reproduce; bisect its content to the offending construct
- File a bug with the offending markdown if valid input triggers it
Example fix
// before: renderer output trusted blindly
data := renderer.Render()
if !json.Valid(data) {
return fmt.Errorf("generated tree [%s] is not valid JSON", tree.HPath)
}
// after (caller): sanitize control characters before transform
markdown = bytes.Map(func(r rune) rune {
if unicode.IsControl(r) && r != '\n' && r != '\t' { return -1 }
return r
}, markdown) Defensive patterns
Strategy: validation
Validate before calling
markdown = bytes.Map(func(r rune) rune {
if unicode.IsControl(r) && r != '\n' && r != '\t' { return -1 }
return r
}, markdown) // strip control chars before transform Try / catch
if err := writeObsidianTempTree(docsTemp, tree); err != nil && strings.Contains(err.Error(), "not valid JSON") {
// isolate the document at err's hpath and bisect its content
} Prevention
- Sanitize control characters from imported markdown before rendering
- Keep the Lute build in sync with the kernel version
- Test-import unusual notes (code blocks, HTML embeds) in isolation first
When it happens
Trigger: renderer.Render() on a JSONRenderer produced bytes that fail json.Valid(data) — typically malformed input trees, a Lute/renderer bug, or binary/invalid data injected into node text during an Obsidian import.
Common situations: Importing notes containing unusual control characters or broken inline constructs that confuse the renderer; running with a mismatched/older Lute build whose renderer emits invalid JSON; the document hpath contains content that leaks into output incorrectly due to a renderer bug.
Understand the failure class
Background: "JSON serialization failed", "not JSON serializable", "Failed to serialize": why JSON marshaling errors happen and how to fix them — this error's family across 46 libraries.
Related errors
- marshal AI editor actions failed: %w
- marshal legacy AI editor actions failed: %w
- marshal box conf [%s] failed: %w
- marshal box document metadata failed: %w
- marshal notebook crypto backup failed: %w
AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11).
Data as JSON: /api/errors/e5d030c7a6223123.
Report an issue: GitHub.