siyuan-note/siyuan · warning · ErrBoxUnindexed
notebook unindexed
Error message
notebook unindexed
What it means
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.
Source
Thrown at kernel/model/tree.go:207
return
}
}
ret, err = dataparser.ParseJSONWithoutFix(data, luteEngine.ParseOptions)
if err != nil {
logging.LogErrorf("parse json to tree [%s] failed: %s", localPath, err)
return
}
return
}
var (
ErrBoxNotFound = errors.New("notebook not found")
ErrBoxClosed = errors.New("notebook closed")
ErrBlockNotFound = errors.New("block not found")
ErrTreeNotFound = errors.New("tree not found")
ErrIndexing = errors.New("indexing")
ErrBoxUnindexed = errors.New("notebook unindexed")
ErrInvalidID = errors.New("invalid id")
)
func LoadTreeByBlockIDWithReindex(id string) (ret *parse.Tree, err error) {
return LoadTreeByBlockIDWithReindexInBox(id, "")
}
// LoadTreeByBlockIDWithReindexInBox 与 LoadTreeByBlockIDWithReindex 一致,但按 boxID 路由 blocktree 查询。
func LoadTreeByBlockIDWithReindexInBox(id, boxID string) (ret *parse.Tree, err error) {
if "" == id {
logging.LogWarnf("block id is empty")
return nil, ErrTreeNotFound
}
bt := treenode.GetBlockTreeInBox(id, boxID)
if nil == bt && "" == boxID {
// boxID 未知时(如通用打开入口),遍历所有已打开的加密笔记本查找
for _, encBoxID := range treenode.GetOpenedEncryptedBoxIDs() {View on GitHub (pinned to 251596fc0d)
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).
Example fix
// before — generic error handling
tree, err := LoadTreeByBlockIDWithReindex(id)
if err != nil { showError(err) }
// after — branch on sentinel
if errors.Is(err, model.ErrBoxUnindexed) {
promptOpenNotebook()
} Defensive patterns
Strategy: validation
Validate before calling
func boxIsIndexed(boxID string) bool {
return model.Conf.Box(boxID) != nil // nil => closed/unindexed
} Try / catch
_, err := model.LoadTreeByBlockIDWithReindex(id)
if errors.Is(err, model.ErrBoxUnindexed) {
promptUserToOpenNotebookByBlock(id)
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- notebook closed
- notebook not found
- notebook [%s] is closed; run `notebook open --id %s` first
- indexing
- encrypted notebook is locked, please unlock it first
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/4a0480cd356e65ee.
Report an issue: GitHub.