{"record":{"id":"4a0480cd356e65ee","repo":"siyuan-note/siyuan","slug":"notebook-unindexed","errorCode":null,"errorMessage":"notebook unindexed","messagePattern":"notebook unindexed","errorType":"error_code","errorClass":"ErrBoxUnindexed","httpStatus":null,"severity":"warning","filePath":"kernel/model/tree.go","lineNumber":207,"sourceCode":"\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)\n\tif nil == bt && \"\" == boxID {\n\t\t// boxID 未知时（如通用打开入口），遍历所有已打开的加密笔记本查找\n\t\tfor _, encBoxID := range treenode.GetOpenedEncryptedBoxIDs() {","sourceCodeStart":189,"sourceCodeEnd":225,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/kernel/model/tree.go#L189-L225","documentation":"Sentinel error ErrBoxUnindexed declared at tree.go:207 ('notebook unindexed'). Returned by indexTreeInFilesystem (tree.go:358) when a block is found on disk via findUnindexedTreePathInAllBoxes, the owning boxID is resolved, but that box exists ONLY in Conf.GetClosedBoxes() (i.e., the notebook is closed/unindexed) — Conf.Box(boxID) returns nil. It indicates the data exists but the notebook must be opened (indexed) first.","triggerScenarios":"A block lookup falls through to the filesystem fallback, finds the .sy file under a notebook that is currently CLOSED (listed in GetClosedBoxes, not GetOpenedBoxes). The code logs 'box [X] is closed', pushes a localized message (Conf.language(197)), and returns ErrBoxUnindexed. block.go API handler checks errors.Is(err, model.ErrBoxUnindexed) to inform the client.","commonSituations":"A closed encrypted notebook contains the referenced block; a notebook the user closed still has docs referenced by bookmarks/history/external links; the kernel rebooted and the notebook was not auto-opened.","solutions":["Open the closed notebook (UI action or API) so it gets indexed, then retry the operation.","Use errors.Is(err, model.ErrBoxUnindexed) to prompt 'notebook X is closed, open it to access this doc'.","Distinguish from ErrBoxNotFound (notebook does not exist at all) and ErrIndexing (transient)."],"exampleFix":"// before — generic error handling\ntree, err := LoadTreeByBlockIDWithReindex(id)\nif err != nil { showError(err) }\n\n// after — branch on sentinel\nif errors.Is(err, model.ErrBoxUnindexed) {\n    promptOpenNotebook()\n}","handlingStrategy":"validation","validationCode":"func boxIsIndexed(boxID string) bool {\n    return model.Conf.Box(boxID) != nil // nil => closed/unindexed\n}","typeGuard":null,"tryCatchPattern":"_, err := model.LoadTreeByBlockIDWithReindex(id)\nif errors.Is(err, model.ErrBoxUnindexed) {\n    promptUserToOpenNotebookByBlock(id)\n}","preventionTips":["Ensure referenced notebooks are opened after kernel boot.","Distinguish ErrBoxUnindexed (open the notebook) from ErrBoxNotFound (gone) and ErrIndexing (wait).","For encrypted notebooks, unlock/open them before docs are referenced."],"tags":["notebook","box","sentinel","indexing","state"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}