{"record":{"id":"a90a28052157a02e","repo":"siyuan-note/siyuan","slug":"get-block-failed","errorCode":null,"errorMessage":"get block failed: ","messagePattern":"get block failed: ","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/api/block_op.go","lineNumber":52,"sourceCode":"func parseBlockUpdateInput(arg map[string]any, ret *gulu.Result) (input model.BlockUpdateInput, ok bool) {\n\tif !util.ParseJsonArgs(arg, ret,\n\t\tutil.BindJsonArg(\"id\", &input.ID, true, true),\n\t\tutil.BindJsonArg(\"data\", &input.Data, true, false),\n\t\tutil.BindJsonArg(\"dataType\", &input.DataType, true, true),\n\t\tutil.BindJsonArg(\"lockType\", &input.LockType, false, false),\n\t) {\n\t\treturn\n\t}\n\tif util.InvalidIDPattern(input.ID, ret) {\n\t\treturn input, false\n\t}\n\treturn input, true\n}\n\nfunc buildUpdatedTaskListItemBlockDOM(id, marker string, luteEngine *lute.Lute) (data string, err error) {\n\tblock, err := model.GetBlock(id, nil)\n\tif err != nil {\n\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\")","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/8641553a1f07374001902d3ce773285db1292b2d/kernel/api/block_op.go#L34-L70","documentation":"buildUpdatedTaskListItemBlockDOM wraps any error from model.GetBlock(id, nil) with the prefix \"get block failed: \". model.GetBlock fails when the block ID cannot be resolved to a row in the blocks index (blocktree), meaning the ID does not exist, is stale, or the notebook is unavailable. The kernel throws this while updating a task list item checkbox because the target list item could not be loaded.","triggerScenarios":"Calling updateTaskListItemMarker or batchUpdateTaskListItemMarker (task checkbox toggle API path) with a block ID that is absent from the in-memory block tree: the document was re-indexed, the block was deleted, the ID is malformed, or the blocktree cache is stale.","commonSituations":"Frontend holds a stale block ID after another client synced deletions; plugin passes an arbitrary string instead of a real .sy block ID; concurrent transaction removed the list item between rendering and checkbox click; notebook not yet indexed after open.","solutions":["Re-fetch the block/tree on the frontend (getBlockByID / reload the document) and retry with a fresh ID","Verify the ID exists via the kernel API /api/query/sql or getBlockInfo before calling the marker update","Check the ID string is a valid 22-char SiYuan block ID with no whitespace or trimming issues","If IDs are systematically stale, reindex the notebook (Rebuild Index) so blocktree matches disk"],"exampleFix":"// before\nupdateTaskListItemMarker(staleId, \"x\", cb);\n// after\nconst info = await fetchSyncPost(\"/api/filetree/getDocInfo\", { id: staleId });\nif (!info || info.code !== 0) { reloadDoc(); return; }\nupdateTaskListItemMarker(staleId, \"x\", cb);","handlingStrategy":"validation","validationCode":"const info = await fetchSyncPost(\"/api/block/getBlockInfo\", { id });\nif (info.code !== 0) { /* skip or reload */ }","typeGuard":null,"tryCatchPattern":"try { await updateTaskListItemMarker(id, \"x\"); } catch (e) { if (String(e).includes(\"get block failed\")) { reloadDoc(); } }","preventionTips":["Always resolve IDs from fresh getBlockInfo calls, not long-lived caches","Refresh IDs after sync/transaction events","Trim and validate ID format before API calls"],"tags":["go","kernel-api","block-not-found","task-list"],"backgroundTag":"record-not-found","analyzedSha":"8641553a1f07374001902d3ce773285db1292b2d","analyzedAt":"2026-09-11T16:08:28.414Z","contentChangedAt":"2026-09-11T16:08:28.414Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}