siyuan-note/siyuan · error
block is not a task list item
Error message
block is not a task list item
What it means
Thrown by buildUpdatedTaskListItemBlockDOM (kernel/api/block_op.go) when the node is a list item but li.ListData.Typ != 3. In Lute's AST, Typ 3 identifies task list items; Typ 1 (bullet) and Typ 2 (ordered) are plain list items with no checkbox marker, so there is nothing for the task-marker API to update.
Source
Thrown at kernel/api/block_op.go:70
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 ]")
}
markerNode := li.ChildByType(ast.NodeTaskListItemMarker)
if nil == markerNode {
return "", errors.New("task list item marker not found")
}
markerNode.TaskListItemMarker = liMarker
markerNode.TaskListItemChecked = ' ' != markerNode.TaskListItemMarkerView on GitHub (pinned to afa823b6b4)
Solutions
- Check ListData type via getBlockKramdown (task items render with [ ] / [x] markers) before calling
- Convert the list to a task list in the editor (retype the marker as [ ]), then call the API
- Filter to task items only in batch operations
- Use the correct API for plain list items (e.g. list marker/type change via transactions) instead of the task-marker endpoint
Example fix
// before
// id belongs to '- plain bullet item'
fetchPost('/api/block/updateTaskListItemMarker', { id, marker: 'x' }); // "block is not a task list item"
// after
const kd = await fetchPost('/api/block/getBlockKramdown', { id });
if (/\[([ xX])\]/.test(kd.data.kramdown)) {
fetchPost('/api/block/updateTaskListItemMarker', { id, marker: 'x' });
} Defensive patterns
Strategy: type-guard
Validate before calling
const kd = await fetchPost('/api/block/getBlockKramdown', { id });
const isTask = /\[[ xX]?\]/.test(kd.data?.kramdown ?? '') || kd.data?.type === 'NodeListItem' && hasTaskMarker(kd.data);
if (!isTask) throw new Error('not a task list item');
await fetchPost('/api/block/updateTaskListItemMarker', { id, marker }); Type guard
function isTaskListItem(kramdown: string): boolean {
return /^\s*(?:[-*+\d.)]+)\s+\[( |x|X)\]/.test(kramdown);
} Try / catch
if (e.message === 'block is not a task list item') { /* convert the list to a task list first, or skip */ } Prevention
- Distinguish list items from task items in your data model
- Re-check kramdown when users retype list styles
- Convert plain lists to task lists in-editor before automating checkbox state
When it happens
Trigger: Passing the id of a bullet-list or ordered-list item to /api/block/updateTaskListItemMarker; the document was converted from a task list to a plain list after the id was captured; batch marker updates applied to mixed lists.
Common situations: A plugin iterates list items and assumes every NodeListItem is a task item; user toggled the list style between -/* and [ ] syntax; imported Markdown where plain lists outnumber task lists.
Related errors
- block is not a list item
- task list item marker length should be 1
- task list item marker can not be [ or ]
- block updates are empty
- get block failed: %s
AI-assisted analysis of siyuan-note/siyuan@afa823b6b4 (2026-08-18).
Data as JSON: /api/errors/68fd965df3880661.
Report an issue: GitHub.