{"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/251596fc0de2f9528c00c224252fd073a99973f4/kernel/model/block_update.go#L95-L131","documentation":"Returned by buildBlockUpdateOperations when loadTree(input.ID) returns a non-nil error. The cache lookup (resolveTree + treeCache) missed, so the loader was invoked; the loader failed for some underlying reason which is wrapped with %w. The ID itself passed IsNodeIDPattern - this is a storage/IO failure.","triggerScenarios":"Missing .sy file for the block's root; corrupted .sy file that fails to unmarshal; filelock contention; disk/permission error; network share hiccup.","commonSituations":"Out-of-band deletion of the .sy file; partial sync that left an incomplete file; mobile storage permission revoked mid-operation.","solutions":["Inspect the wrapped error (errors.Unwrap or %w chain) for the OS-level cause.","Verify the .sy file exists at the expected path under data/<box>/<path>.sy.","Restore from history/snapshot if the file is corrupted.","Rebuild the index after restoring the file."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"if _, err := os.Stat(expectedSyPath(id)); err != nil {\n    return fmt.Errorf(\"sy file missing for %s\", id)\n}","typeGuard":null,"tryCatchPattern":"ops, roots, err := buildBlockUpdateOperations(inputs, resolver, loader)\nif err != nil {\n    if cause := errors.Unwrap(err); cause != nil {\n        log.Warnf(\"load failed: %v\", cause)\n    }\n    // fall back: rebuild index, then retry once\n}","preventionTips":["Ensure the .sy file for the root exists on disk before updates.","Keep snapshots/history enabled so corrupted .sy files can be restored.","Inspect wrapped errors with errors.Unwrap to find the OS-level cause."],"tags":["block-update","filesystem","io-error","load-tree"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}