{"record":{"id":"07f4fc6f49446008","repo":"siyuan-note/siyuan","slug":"block-not-found","errorCode":null,"errorMessage":"block not found","messagePattern":"block not found","errorType":"validation","errorClass":null,"httpStatus":200,"severity":"error","filePath":"kernel/api/block_op.go","lineNumber":66,"sourceCode":"\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\")\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\")","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/afa823b6b4e4f183511e0bc0a3be93caa94c7c97/kernel/api/block_op.go#L48-L84","documentation":"Thrown by buildUpdatedTaskListItemBlockDOM (kernel/api/block_op.go) when the .sy tree loads successfully but treenode.GetNodeInTree cannot find a node with the given id inside it. The SQL index believes the block lives in this document, but the in-memory tree disagrees — an index/tree desynchronization, not a bad file.","triggerScenarios":"The block was moved or deleted in the editor while its SQL index row was not yet updated (async indexing lag); a transaction failed halfway leaving index and document inconsistent; the same block id is referenced from a different document than the one indexed; workspace restored partially so index and .sy files diverge.","commonSituations":"Rapid successive edits where the API is called between the write and the index flush; kernel killed before the async index queue drained; sync conflicts resolved by keeping one side's .sy but the other side's index; plugin holds ids longer than the document lifetime.","solutions":["Retry after a short delay — if it is index lag, the flush (FlushTxQueue) will reconcile the tree and index","Verify with /api/block/getBlockInfo which rootID/path the index currently claims, and open that document to confirm the block exists","Trigger a reindex of the affected notebook so index and trees reconverge","If the block was truly deleted, discard the stale id and stop updating it"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const info = await fetchPost('/api/block/getBlockInfo', { id });\nif (info.code !== 0) throw new Error('block unknown to index');\nconst root = info.data.root_id;\n// confirm the doc still contains the block before mutating\nconst doc = await fetchPost('/api/filetree/getDoc', { id: root });\nif (!doc.data?.includes?.(id)) throw new Error('stale block id');","typeGuard":"const isLiveBlockId = (id: string, docContent: string): boolean => docContent.includes(`\"${id}\"`);","tryCatchPattern":"if (e.message === 'block not found') {\n  // index/tree mismatch: wait one flush interval, re-fetch block info, retry once; else drop the id\n}","preventionTips":["Treat captured block ids as ephemeral; re-verify before use","Retry once after FlushTxQueue settles — most cases are async-index lag","Reindex the notebook when mismatches persist"],"tags":["block","index","consistency","api","siyuan"],"backgroundTag":"block-not-found","analyzedSha":"afa823b6b4e4f183511e0bc0a3be93caa94c7c97","analyzedAt":"2026-08-18T17:04:10.865Z","schemaVersion":2},"datasetVersion":"2026-08-31T22:30:34.772Z"}