siyuan-note/siyuan · error
block is not a list item
Error message
block is not a list item
What it means
After fetching the block, buildUpdatedTaskListItemBlockDOM requires block.Type == "NodeListItem"; any other block type (paragraph, heading, etc.) makes the task-list-item DOM update meaningless, so it fails with this error.
Solutions
- Pass the NodeListItem block's ID, not a child node's ID
- Re-read the block's type via /api/filetree/getDoc or getBlockInfo and route non-item blocks elsewhere
- If the item lost its task marker, re-apply the task formatting first
Example fix
// before updateTaskItem(childParagraphId) // after const parentId = block.parentID // NodeListItem updateTaskItem(parentId)
Defensive patterns
Strategy: validation
Validate before calling
const info = await fetchPost('/api/block/getBlockInfo', {id});
if (info.data.type !== 'NodeListItem') throw new Error('not a list item'); Type guard
const isListItem = (b) => b?.type === 'NodeListItem';
Try / catch
try { await updateTaskItem(id, marker) } catch (e) { if (String(e).includes('not a list item')) await redirectToGenericBlockUpdate(id) } Prevention
- Resolve the closest NodeListItem ancestor before task-specific calls
- Re-read block type after any structural transaction
- Centralize block-type assertions in one client helper
When it happens
Trigger: Calling the task list item update operation with a block ID that resolves to a non-list-item block, e.g. a paragraph inside a task item rather than the item itself.
Common situations: Client grabbing the inner text block's ID instead of the li block ID; document structure changed (task marker removed) so the block is now a plain paragraph; plugin assumptions about older content.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- block is not a task list item
- block [ ] type is locked: expected , got
- Field [id] should be of type [String]
- Field [level] should be of type [Number]
- Field [notebook] should be of type [String]
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/289580e315e1092e.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/api/block_op.go:41
"github.com/88250/gulu"
"github.com/88250/lute"
"github.com/88250/lute/ast"
"github.com/gin-gonic/gin"
"github.com/siyuan-note/siyuan/kernel/apicontract"
"github.com/siyuan-note/siyuan/kernel/filesys"
"github.com/siyuan-note/siyuan/kernel/model"
"github.com/siyuan-note/siyuan/kernel/treenode"
"github.com/siyuan-note/siyuan/kernel/util"
)
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")View on GitHub (pinned to 9f775e8a12)