{"record":{"id":"07e8c4938ec04ccd","repo":"siyuan-note/siyuan","slug":"block-not-found-07e8c4","errorCode":null,"errorMessage":"block not found","messagePattern":"block not found","errorType":"error_code","errorClass":"ErrBlockNotFound","httpStatus":null,"severity":"error","filePath":"kernel/model/tree.go","lineNumber":204,"sourceCode":"\t\trelPath := filepath.ToSlash(strings.TrimPrefix(localPath, filepath.Join(util.DataDir, boxID)+string(os.PathSeparator)))\n\t\tif data, err = DecryptFile(boxID, relPath, dek, data); err != nil {\n\t\t\tlogging.LogErrorf(\"decrypt tree [path=%s] failed: %s\", localPath, err)\n\t\t\treturn\n\t\t}\n\t}\n\n\tret, err = dataparser.ParseJSONWithoutFix(data, luteEngine.ParseOptions)\n\tif err != nil {\n\t\tlogging.LogErrorf(\"parse json to tree [%s] failed: %s\", localPath, err)\n\t\treturn\n\t}\n\treturn\n}\n\nvar (\n\tErrBoxNotFound   = errors.New(\"notebook not found\")\n\tErrBoxClosed     = errors.New(\"notebook closed\")\n\tErrBlockNotFound = errors.New(\"block not found\")\n\tErrTreeNotFound  = errors.New(\"tree not found\")\n\tErrIndexing      = errors.New(\"indexing\")\n\tErrBoxUnindexed  = errors.New(\"notebook unindexed\")\n\tErrInvalidID     = errors.New(\"invalid id\")\n)\n\nfunc LoadTreeByBlockIDWithReindex(id string) (ret *parse.Tree, err error) {\n\treturn LoadTreeByBlockIDWithReindexInBox(id, \"\")\n}\n\n// LoadTreeByBlockIDWithReindexInBox 与 LoadTreeByBlockIDWithReindex 一致，但按 boxID 路由 blocktree 查询。\nfunc LoadTreeByBlockIDWithReindexInBox(id, boxID string) (ret *parse.Tree, err error) {\n\tif \"\" == id {\n\t\tlogging.LogWarnf(\"block id is empty\")\n\t\treturn nil, ErrTreeNotFound\n\t}\n\n\tbt := treenode.GetBlockTreeInBox(id, boxID)","sourceCodeStart":186,"sourceCodeEnd":222,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/kernel/model/tree.go#L186-L222","documentation":"Sentinel error ErrBlockNotFound declared at tree.go:204 ('block not found'). The most widely thrown sentinel — returned by heading/block/assets/search/transaction/template operations when a block ID has no blocktree entry (treenode.GetBlockTree returns nil). Callers compare with errors.Is(err, model.ErrBlockNotFound). Throw sites include heading.go (many), block.go, assets.go:1216, search.go, transaction.go (TxErr wrapping), template.go:382.","triggerScenarios":"Referencing a block ID that was deleted, never existed, or whose blocktree entry was lost; a block-ref/heading operation on a stale ID; an AV operation referencing a missing block; transaction processing where an ID in the tx no longer resolves.","commonSituations":"A block was deleted but a reference (block-ref, heading fold, bookmark) still points to it; the blocktree.db is corrupted or out of sync with the .sy files; a plugin passes an invalid or truncated block ID; cross-workspace reference where the target block is absent.","solutions":["Validate the block ID exists via treenode.GetBlockTree(id) before the operation.","If the blocktree is suspected out of sync, trigger a reindex of the notebook.","For UI references, detect ErrBlockNotFound and offer to remove/repair the dangling reference.","Use errors.Is(err, model.ErrBlockNotFound) — never string-match the message."],"exampleFix":"// before — assume block exists\nbt := treenode.GetBlockTree(id)\noperateOnBlock(bt) // nil panic or ErrBlockNotFound\n\n// after — guard\nbt := treenode.GetBlockTree(id)\nif bt == nil {\n    return ErrBlockNotFound\n}","handlingStrategy":"validation","validationCode":"func blockExists(id string) bool {\n    return treenode.GetBlockTree(id) != nil\n}","typeGuard":null,"tryCatchPattern":"err := op(blockID)\nif errors.Is(err, model.ErrBlockNotFound) {\n    // offer to repair/remove the dangling reference\n}","preventionTips":["Validate block IDs via treenode.GetBlockTree before block-scoped operations.","If blocktree seems stale, reindex the notebook.","Use errors.Is(err, model.ErrBlockNotFound) for precise branching."],"tags":["block","sentinel","not-found","blocktree","validation"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}