{"record":{"id":"3bcf78442e3f79f8","repo":"siyuan-note/siyuan","slug":"load-block-tree-s-failed-w","errorCode":null,"errorMessage":"load block tree [%s] failed: %w","messagePattern":"load block tree \\[(.+?)\\] failed: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/block_update.go","lineNumber":113,"sourceCode":"\n\t\tdata, dataTree, parseErr := parseBlockUpdateData(input.Data, input.DataType, luteEngine)\n\t\tif parseErr != nil {\n\t\t\treturn nil, nil, parseErr\n\t\t}\n\n\t\tvar oldTree *parse.Tree\n\t\tvar cacheKey blockUpdateTreeKey\n\t\thasCacheKey := false\n\t\tif blockTree := resolveTree(input.ID); nil != blockTree {\n\t\t\tcacheKey = blockUpdateTreeKey{boxID: blockTree.BoxID, rootID: blockTree.RootID}\n\t\t\thasCacheKey = true\n\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}","sourceCodeStart":95,"sourceCodeEnd":131,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/model/block_update.go#L95-L131","documentation":"When buildBlockUpdateOperations cannot load the existing tree for an input ID (cache miss and loadTree returns an error), it wraps the failure as \"load block tree [%s] failed: %w\" with the ID and underlying cause. This means the block's document could not be read from disk/index before applying the update.","triggerScenarios":"Updating a block whose document file is missing or unreadable — notebook not fully indexed, .sy file deleted by sync, disk/permission error, or the ID belongs to a closed/removed notebook.","commonSituations":"Sync races deleting the document between the UI read and the update; workspace data directory moved or partially copied; failing disk or read-only filesystem; notebook removed while a plugin still references its blocks.","solutions":["Check that the notebook containing the block still exists and the .sy file is present under data/<box>/.siyuan? read via /api/filetree/getHPathByID.","Rebuild the index (设置 - 关于 - rebuild / /api/filetree/refreshFiletree or full reindex) if the doc was just synced.","Inspect the wrapped cause (%w) in server logs to distinguish ENOENT from permission errors.","Restore the missing document from sync/history before retrying the update."],"exampleFix":"// before\nawait updateBlock(id, newData); // fails if doc file is gone\n// after\nconst info = await fetchPost('/api/filetree/getHPathByID', { id });\nif (info.code !== 0) { await restoreFromHistoryOrSync(id); }\nawait updateBlock(id, newData);","handlingStrategy":"fallback","validationCode":"async function treeLoadable(id) {\n  const res = await fetchPost('/api/filetree/getHPathByID', { id });\n  return res.code === 0;\n}","typeGuard":null,"tryCatchPattern":"try { await updateBlocks(inputs); } catch (e) { if (String(e.msg).includes('load block tree')) { await restoreDocFromHistoryOrSync(id); await updateBlocks(inputs); } else throw e; }","preventionTips":["Confirm notebooks are fully indexed/synced before bulk updates.","Watch the wrapped cause in server logs to distinguish missing files from permission errors.","Avoid updating blocks in notebooks that are mid-sync or mid-reindex."],"tags":["tree-load-failed","filesystem","sync","kernel"],"backgroundTag":"file-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"}