{"record":{"id":"7c934b65c7c5e43a","repo":"siyuan-note/siyuan","slug":"errindexing","errorCode":"ErrIndexing","errorMessage":"indexing","messagePattern":"indexing","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"kernel/model/tree.go","lineNumber":214,"sourceCode":"\t}\n\n\tif err = treenode.CheckSpecJSON(data); nil != err {\n\t\treturn\n\t}\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 未知时（如通用打开入口），遍历所有已打开的加密笔记本查找","sourceCodeStart":196,"sourceCodeEnd":232,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/8641553a1f07374001902d3ce773285db1292b2d/kernel/model/tree.go#L196-L232","documentation":"ErrIndexing is the sentinel error meaning the requested tree/block is currently being re-indexed and is not yet available. Functions like getDocInfo, getBlockInfo, and LoadTreeByBlockIDWithReindex return it to tell API handlers the operation is transient; handlers respond with a localized 'indexing' message (Language(56)) or a special code (3) so clients retry.","triggerScenarios":"Requesting block/doc info while a notebook's index queue is actively rebuilding (freshly opened workspace, import, or reindex operation); LoadTreeByBlockIDWithReindex detecting an index miss and kicking off reindexing.","commonSituations":"Frontend loads immediately after app start or after a large import before indexing finishes; scripts/automations racing with a Rebuild Index operation; a newly created notebook queried before its first index completes.","solutions":["Wait briefly and retry the same request until indexing finishes (the API returns code 3 to signal retry)","Wait for the index-queue idle / task-complete WebSocket push before running scripts against fresh workspaces","Do not treat this as fatal — check errors.Is(err, model.ErrIndexing) and return a localized 'indexing in progress' message instead of an error"],"exampleFix":"// before\nret.Msg = err.Error()\n// after\nif errors.Is(err, model.ErrIndexing) {\n    ret.Code = 3\n    ret.Msg = model.Conf.Language(56)\n}","handlingStrategy":"retry","validationCode":"for i := 0; i < 10; i++ {\n    info, err := getBlockInfo(id)\n    if err == nil || !errors.Is(err, model.ErrIndexing) { break }\n    time.Sleep(500 * time.Millisecond)\n}","typeGuard":null,"tryCatchPattern":"if errors.Is(err, model.ErrIndexing) {\n    ret.Code = 3\n    ret.Msg = model.Conf.Language(56) // client retries\n    return\n}","preventionTips":["Delay scripts until after workspace indexing completes","Listen for index/task-complete pushes before querying fresh imports","Do not query a notebook immediately after creating it"],"tags":["go","indexing","transient"],"backgroundTag":"operation-not-supported","analyzedSha":"8641553a1f07374001902d3ce773285db1292b2d","analyzedAt":"2026-09-11T16:08:28.414Z","contentChangedAt":"2026-09-11T16:08:28.414Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}