siyuan-note/siyuan · error
Query notebook failed
Error message
Query notebook failed
What it means
Thrown by ListDocTree when Conf.Box(boxID) returns nil, meaning no notebook with the given boxID is registered in the current configuration. Conf.Language(0) = 'Query notebook failed'. This is a pure lookup failure — the ID does not match any loaded notebook, the notebook was deleted, or it has not been opened/initialized yet.
Source
Thrown at kernel/model/file.go:404
ret = []*File{}
if flashcard && IsEncryptedBox(boxID) {
return nil, 0, errors.New(Conf.Language(313))
}
var deck *riff.Deck
var deckBlockIDs []string
if flashcard {
deck = Decks[builtinDeckID]
if nil == deck {
return
}
deckBlockIDs = deck.GetBlockIDs()
}
box := Conf.Box(boxID)
if nil == box {
return nil, 0, errors.New(Conf.Language(0))
}
boxConf := box.GetConf()
if util.SortModeUnassigned == sortMode {
sortMode = Conf.FileTree.Sort
if util.SortModeFileTree != boxConf.SortMode {
sortMode = boxConf.SortMode
}
}
var files []*FileInfo
start := time.Now()
files, totals, err = box.Ls(listPath)
if err != nil {
return
}
elapsed := time.Since(start).Milliseconds()View on GitHub (pinned to 251596fc0d)
Solutions
- Verify the boxID exists by calling Conf.Box(boxID) or listing available notebooks before invoking ListDocTree.
- If the notebook was recently created or imported, ensure the kernel has finished loading it — call the notebook refresh/reload API first.
- Refresh the client-side notebook list to discard stale IDs after workspace switches or notebook deletion.
- Check kernel logs for notebook load failures at startup that may explain why the box isn't registered.
Example fix
// before
files, totals, err := model.ListDocTree(boxID, path, sort, flashcard, show, max)
// after
if nil == conf.Box(boxID) {
return nil, 0, fmt.Errorf("notebook %s is not available", boxID)
}
files, totals, err := model.ListDocTree(boxID, path, sort, flashcard, show, max) Defensive patterns
Strategy: validation
Validate before calling
// Pre-check: validate boxID exists before listing
if conf.Box(boxID) == nil {
return nil, 0, fmt.Errorf("notebook %s does not exist", boxID)
} Type guard
func notebookExists(boxID string) bool {
return conf.Box(boxID) != nil
} Prevention
- Always validate boxID via conf.Box(boxID) before calling ListDocTree.
- Refresh the notebook list in the UI after workspace switches or notebook deletion.
- For API clients, re-fetch notebooks at session start and cache only for the session.
When it happens
Trigger: Calling ListDocTree with a boxID that does not exist in Conf.GetOpenedBoxes() or Conf.GetBoxes(). Common when the ID is stale (notebook was removed), mistyped, or belongs to a notebook that exists on disk but hasn't been loaded into Conf state.
Common situations: A frontend tab or plugin holds a stale notebook ID after the user deleted or closed the notebook. A sync conflict removed a notebook but the UI wasn't refreshed. The workspace was switched but cached IDs persisted.
Related errors
- invalid box id
- new item template field [%s] not found
- new item template field [%s] option [%s] not found
- path belongs to encrypted notebook [%s]: %s
- --notebook is required
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/fc5103da5c50f084.
Report an issue: GitHub.