{"record":{"id":"68fd965df3880661","repo":"siyuan-note/siyuan","slug":"block-is-not-a-task-list-item","errorCode":null,"errorMessage":"block is not a task list item","messagePattern":"block is not a task list item","errorType":"validation","errorClass":null,"httpStatus":200,"severity":"error","filePath":"kernel/api/block_op.go","lineNumber":70,"sourceCode":"\t\treturn \"\", errors.New(\"get block failed: \" + err.Error())\n\t}\n\n\tif \"NodeListItem\" != block.Type {\n\t\treturn \"\", errors.New(\"block is not a list item\")\n\t}\n\n\ttree, err := filesys.LoadTree(block.Box, block.Path, luteEngine)\n\tif err != nil {\n\t\treturn \"\", errors.New(\"load tree failed: \" + err.Error())\n\t}\n\n\tli := treenode.GetNodeInTree(tree, id)\n\tif li == nil {\n\t\treturn \"\", errors.New(\"block not found\")\n\t}\n\n\tif 3 != li.ListData.Typ {\n\t\treturn \"\", errors.New(\"block is not a task list item\")\n\t}\n\n\tif 1 != len(marker) {\n\t\treturn \"\", errors.New(\"task list item marker length should be 1\")\n\t}\n\n\tliMarker := marker[0]\n\tif '[' == liMarker || ']' == liMarker {\n\t\treturn \"\", errors.New(\"task list item marker can not be [ or ]\")\n\t}\n\n\tmarkerNode := li.ChildByType(ast.NodeTaskListItemMarker)\n\tif nil == markerNode {\n\t\treturn \"\", errors.New(\"task list item marker not found\")\n\t}\n\n\tmarkerNode.TaskListItemMarker = liMarker\n\tmarkerNode.TaskListItemChecked = ' ' != markerNode.TaskListItemMarker","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/afa823b6b4e4f183511e0bc0a3be93caa94c7c97/kernel/api/block_op.go#L52-L88","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\n// id belongs to '- plain bullet item'\nfetchPost('/api/block/updateTaskListItemMarker', { id, marker: 'x' }); // \"block is not a task list item\"\n\n// after\nconst kd = await fetchPost('/api/block/getBlockKramdown', { id });\nif (/\\[([ xX])\\]/.test(kd.data.kramdown)) {\n  fetchPost('/api/block/updateTaskListItemMarker', { id, marker: 'x' });\n}","handlingStrategy":"type-guard","validationCode":"const kd = await fetchPost('/api/block/getBlockKramdown', { id });\nconst isTask = /\\[[ xX]?\\]/.test(kd.data?.kramdown ?? '') || kd.data?.type === 'NodeListItem' && hasTaskMarker(kd.data);\nif (!isTask) throw new Error('not a task list item');\nawait fetchPost('/api/block/updateTaskListItemMarker', { id, marker });","typeGuard":"function isTaskListItem(kramdown: string): boolean {\n  return /^\\s*(?:[-*+\\d.)]+)\\s+\\[( |x|X)\\]/.test(kramdown);\n}","tryCatchPattern":"if (e.message === 'block is not a task list item') { /* convert the list to a task list first, or skip */ }","preventionTips":["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"],"tags":["block","task-list","validation","api","siyuan"],"backgroundTag":"wrong-block-type","analyzedSha":"afa823b6b4e4f183511e0bc0a3be93caa94c7c97","analyzedAt":"2026-08-18T17:04:10.865Z","schemaVersion":2},"datasetVersion":"2026-08-31T22:30:34.772Z"}