{"record":{"id":"ecf09791c3c95326","repo":"siyuan-note/siyuan","slug":"block-s-not-found","errorCode":null,"errorMessage":"block [%s] not found","messagePattern":"block \\[(.+?)\\] not found","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/block_update.go","lineNumber":125,"sourceCode":"\t\t\toldTree = treeCache[cacheKey]\n\t\t}\n\t\tif nil == oldTree {\n\t\t\tvar loadErr error\n\t\t\toldTree, loadErr = loadTree(input.ID)\n\t\t\tif loadErr != nil {\n\t\t\t\treturn nil, nil, fmt.Errorf(\"load block tree [%s] failed: %w\", input.ID, loadErr)\n\t\t\t}\n\t\t\tif nil == oldTree || nil == oldTree.Root {\n\t\t\t\treturn nil, nil, fmt.Errorf(\"load block tree [%s] failed: tree is empty\", input.ID)\n\t\t\t}\n\t\t\ttreeCache[blockUpdateTreeKey{boxID: oldTree.Box, rootID: oldTree.ID}] = oldTree\n\t\t\tif hasCacheKey {\n\t\t\t\ttreeCache[cacheKey] = oldTree\n\t\t\t}\n\t\t}\n\t\toldNode := treenode.GetNodeInTree(oldTree, input.ID)\n\t\tif nil == oldNode {\n\t\t\treturn nil, nil, fmt.Errorf(\"block [%s] not found\", input.ID)\n\t\t}\n\n\t\tif _, ok := rootIDSet[oldTree.ID]; !ok {\n\t\t\trootIDSet[oldTree.ID] = struct{}{}\n\t\t\trootIDs = append(rootIDs, oldTree.ID)\n\t\t}\n\n\t\tif ast.NodeDocument == oldNode.Type {\n\t\t\tif validateErr := treenode.ValidateBlockSubtree(dataTree.Root); validateErr != nil {\n\t\t\t\treturn nil, nil, validateErr\n\t\t\t}\n\t\t\tfor n := oldTree.Root.FirstChild; nil != n; n = n.Next {\n\t\t\t\tif !n.IsBlock() || ast.NodeKramdownBlockIAL == n.Type {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\toperations = append(operations, &Operation{Action: \"delete\", ID: n.ID, Data: map[string]any{\n\t\t\t\t\t\"createEmptyParagraph\": false, // 清空文档后前端不要创建空段落\n\t\t\t\t}})","sourceCodeStart":107,"sourceCodeEnd":143,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/model/block_update.go#L107-L143","documentation":"Even after the tree loads successfully, the target node may not exist within it; buildBlockUpdateOperations looks up input.ID with treenode.GetNodeInTree and returns \"block [%s] not found\" when nil. The batch update is aborted before any operations are created.","triggerScenarios":"Updating a block ID that the tree cache/load produced a tree for but that contains no matching node: stale ID from a deleted block, ID pointing into a different document, or a root/document ID passed to the block update API.","commonSituations":"Plugins holding editor state across document reloads; concurrent deletion via another window/device; automation updating lists of IDs captured from an outdated query.","solutions":["Re-fetch current block IDs (/api/query/sql or /api/block/getBlockInfo) and retry only with existing IDs.","Per-block, verify the ID's root: SELECT root_id FROM blocks WHERE id='<id>' and ensure the update targets that document's current state.","Catch this error per batch item and skip/queue rather than aborting unrelated updates.","If the block was deleted, recreate it via insert API rather than update."],"exampleFix":"// before\nfor (const item of updates) await updateBlock(item.id, item.data);\n// after\nfor (const item of updates) {\n  const info = await fetchPost('/api/block/getBlockInfo', { id: item.id });\n  if (info.code === 0) await updateBlock(item.id, item.data);\n  else console.warn(`skipping missing block ${item.id}`);\n}","handlingStrategy":"validation","validationCode":"async function nodeInCurrentTree(id) {\n  const res = await fetchPost('/api/block/getBlockInfo', { id });\n  return res.code === 0;\n}","typeGuard":null,"tryCatchPattern":"try { await updateBlocks(inputs); } catch (e) { if (String(e.msg).match(/block \\[.+\\] not found/)) { inputs = await revalidateIds(inputs); if (inputs.length) await updateBlocks(inputs); } else throw e; }","preventionTips":["Re-validate IDs after any document reload, sync, or undo.","Process updates per-item so one stale ID doesn't discard the rest.","Compare the ID's root_id with the document you believe you're editing."],"tags":["block-not-found","stale-id","block-update","kernel"],"backgroundTag":"entity-not-found","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}