siyuan-note/siyuan · error
code block has no code node
Error message
code block has no code node
What it means
Returned by ExportCodeBlock when the node IS a NodeCodeBlock but it has no child of type NodeCodeBlockCode. A well-formed code block in SiYuan's AST always contains a code-content child node; its absence indicates a malformed or corrupted tree — the block was created or migrated incorrectly.
Source
Thrown at kernel/model/export.go:117
err = withExportReadLockByBlockID(blockID, func() error {
tree, _ := LoadTreeByBlockID(blockID)
if nil == tree {
return ErrBlockNotFound
}
node := treenode.GetNodeInTree(tree, blockID)
if nil == node {
return ErrBlockNotFound
}
if ast.NodeCodeBlock != node.Type {
return errors.New("not a code block")
}
code := node.ChildByType(ast.NodeCodeBlockCode)
if nil == code {
return errors.New("code block has no code node")
}
name := tree.Root.IALAttr("title") + "-" + util.CurrentTimeSecondsStr() + ".txt"
name = util.FilterFileName(name)
exportFolder := filepath.Join(util.TempDir, "export")
// 加密笔记本的导出归入 boxID 子目录,确保 LockBox 清理和服务端校验锁定状态
if IsEncryptedBox(tree.Box) {
exportFolder = filepath.Join(exportFolder, tree.Box)
}
exportFolder = filepath.Join(exportFolder, "code")
if mkdirErr := os.MkdirAll(exportFolder, 0755); mkdirErr != nil {
return mkdirErr
}
code.Tokens = bytes.ReplaceAll(code.Tokens, []byte(editor.Zwj+"```"), []byte("```"))
writePath := filepath.Join(exportFolder, name)
if writeErr := filelock.WriteFile(writePath, code.Tokens); writeErr != nil {View on GitHub (pinned to 251596fc0d)
Solutions
- Open the document in the SiYuan editor and re-create the code block — the editor will write a well-formed AST.
- If the .sy file is hand-edited, ensure the code block node has a child with Type = NodeCodeBlockCode containing the code text in Tokens.
- For batch corruption, run the notebook repair/re-index function to rebuild the block tree.
Defensive patterns
Strategy: validation
Try / catch
path, err := model.ExportCodeBlock(blockID)
if err != nil {
if strings.Contains(err.Error(), "no code node") {
// malformed AST — guide user to re-create the block
}
return err
} Prevention
- Avoid hand-editing .sy JSON files.
- Run notebook repair/re-index if code blocks are malformed.
- After migration/import, spot-check code blocks render correctly before bulk export.
When it happens
Trigger: LoadTreeByBlockID returns a tree where the code-block node exists but its child structure is broken (missing NodeCodeBlockCode child). Happens with hand-edited .sy files, buggy import/migration, or partial sync data.
Common situations: Imported a Markdown file that produced a partial code-block node. Sync conflict resolution dropped the code-content child. Manual editing of the .sy JSON damaged the tree structure. A very old SiYuan version created the block with a different child layout.
Related errors
- not a code block
- export source [%s] is not a regular file
- --id is required
- --output is required for docx
- parse json [%s] to tree failed: %w
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/cc30e65d7b7b65f2.
Report an issue: GitHub.