siyuan-note/siyuan · error
load tree failed: %s
Error message
load tree failed: %s
What it means
Third failure mode of buildUpdatedTaskListItemBlockDOM (kernel/api/block_op.go): the block was found in the index and is a list item, but filesys.LoadTree failed to load the .sy document file for block.Box/block.Path. The underlying filesystem error is appended to the prefix, so the message tells you whether it was a missing file, permission problem, or parse failure.
Source
Thrown at kernel/api/block_op.go:61
if util.InvalidIDPattern(input.ID, ret) {
return input, false
}
return input, true
}
func buildUpdatedTaskListItemBlockDOM(id, marker string, luteEngine *lute.Lute) (data string, err error) {
block, err := model.GetBlock(id, nil)
if err != nil {
return "", errors.New("get block failed: " + err.Error())
}
if "NodeListItem" != block.Type {
return "", errors.New("block is not a list item")
}
tree, err := filesys.LoadTree(block.Box, block.Path, luteEngine)
if err != nil {
return "", errors.New("load tree failed: " + err.Error())
}
li := treenode.GetNodeInTree(tree, id)
if li == nil {
return "", errors.New("block not found")
}
if 3 != li.ListData.Typ {
return "", errors.New("block is not a task list item")
}
if 1 != len(marker) {
return "", errors.New("task list item marker length should be 1")
}
liMarker := marker[0]
if '[' == liMarker || ']' == liMarker {
return "", errors.New("task list item marker can not be [ or ]")View on GitHub (pinned to afa823b6b4)
Solutions
- Check the notebook is mounted and the .sy file exists on disk at the path reported in the block info
- Remount/reopen the notebook and retry the update
- If the file is missing but content matters, recover from history (.siyuan/history or /api/history/) or the data repo
- Rebuild the index so stale entries pointing at gone files are cleaned up; inspect the appended underlying error in the kernel log
Defensive patterns
Strategy: validation
Validate before calling
const info = await fetchPost('/api/block/getBlockInfo', { id });
const nb = await fetchGet('/api/notebook/lsNotebooks');
const mounted = nb.data.notebooks.some(n => n.id === info.data.box && !n.closed);
if (!mounted) throw new Error('notebook not mounted; open it before updating');
await fetchPost('/api/block/updateTaskListItemMarker', { id, marker }); Type guard
const isMountedNotebook = (boxId: string, notebooks: { id: string; closed: boolean }[]): boolean =>
notebooks.some(n => n.id === boxId && !n.closed); Try / catch
if (/^load tree failed:/.test(e.message)) {
// underlying fs error: check .sy exists on disk, remount notebook, or reindex; retry after fix
} Prevention
- Do not close/unmount notebooks while automated block updates run
- Let external tools write .sy files only through the kernel, never alongside it
- On load failures, verify the file on disk before retrying blindly
When it happens
Trigger: The .sy file was deleted, moved, or renamed on disk while its index entry survived (unmounted notebook, external file manipulation, interrupted sync); the notebook containing the block is closed/unmounted between index read and tree load; the .sy file is corrupted and cannot be parsed; filesystem permission or disk errors.
Common situations: Sync tool rewrote the notebook directory mid-call; user closed the notebook in another window; .sy files edited by external scripts or merged badly; antivirus/locking software blocking reads on Windows.
Related errors
- get block failed: %s
- block is not a list item
- block not found
- block is not a task list item
- export source [%s] is not a regular file
AI-assisted analysis of siyuan-note/siyuan@afa823b6b4 (2026-08-18).
Data as JSON: /api/errors/362d24e6f5a4285a.
Report an issue: GitHub.