siyuan-note/siyuan · error
notebook [%s] not found
Error message
notebook [%s] not found
What it means
Thrown by SetFileTreeSort when a SortItem in notebookSorts references a notebook ID that does not exist in the current configuration (the boxes map, built from Conf.GetBoxes()). This means the client is trying to persist a sort order for a notebook that has been deleted, was never created, or whose ID was fabricated.
Source
Thrown at kernel/model/file.go:2594
openedBoxes := map[string]*Box{}
for _, box := range Conf.GetOpenedBoxes() {
openedBoxes[box.ID] = box
}
notebookPlans := make([]*notebookSortPlan, 0, len(notebookSorts))
notebookIDs := map[string]struct{}{}
for _, item := range notebookSorts {
if nil == item {
return ret, errors.New("notebook sort item must not be nil")
}
if _, ok := notebookIDs[item.ID]; ok {
return ret, fmt.Errorf("duplicate notebook ID [%s]", item.ID)
}
notebookIDs[item.ID] = struct{}{}
box := boxes[item.ID]
if nil == box {
return ret, fmt.Errorf("notebook [%s] not found", item.ID)
}
notebookPlans = append(notebookPlans, ¬ebookSortPlan{item: item, box: box})
}
docPlans := make([]*docSortPlan, 0, len(docSorts))
docIDs := map[string]struct{}{}
for _, item := range docSorts {
if nil == item {
return ret, errors.New("document sort item must not be nil")
}
if _, ok := docIDs[item.ID]; ok {
return ret, fmt.Errorf("duplicate document ID [%s]", item.ID)
}
docIDs[item.ID] = struct{}{}
bt := treenode.GetBlockTree(item.ID)
if nil == bt || nil == openedBoxes[bt.BoxID] {
return ret, fmt.Errorf("document [%s] not found in opened and unlocked notebooks", item.ID)View on GitHub (pinned to 251596fc0d)
Solutions
- Refresh the notebook list from the kernel (e.g. GET /api/notebook/lsNotebooks) before attempting to persist sort order, so the UI only sends IDs that currently exist.
- If building an API client, validate each notebookSorts ID against the list of known box IDs returned by the notebook listing endpoint before calling setFileTreeSort.
- If the error persists, check whether the notebook was deleted by another session or via sync — reload the workspace configuration.
Example fix
// before
await post('/api/filetree/setFileTreeSort', { notebookSorts, docSorts: [] })
// after
const { notebooks } = await get('/api/notebook/lsNotebooks')
const validIds = new Set(notebooks.map(n => n.id))
const filtered = notebookSorts.filter(item => validIds.has(item.id))
await post('/api/filetree/setFileTreeSort', { notebookSorts: filtered, docSorts: [] }) Defensive patterns
Strategy: validation
Validate before calling
// Validate notebook IDs exist before persisting sort order
const { notebooks } = await get('/api/notebook/lsNotebooks')
const validBoxIds = new Set(notebooks.map(n => n.id))
const validNotebookSorts = notebookSorts.filter(item => validBoxIds.has(item.id)) Prevention
- Refresh the notebook list from the kernel before persisting sort order.
- Handle notebook deletion events (WebSocket push) to remove stale IDs from UI state.
- In multi-session setups, re-sync the notebook list after long idle periods.
When it happens
Trigger: Calling POST /api/filetree/setFileTreeSort with a notebookSorts entry whose id does not match any notebook returned by Conf.GetBoxes(). Common when a notebook was deleted in another session/tab but the file tree UI in the current session still holds the stale ID and includes it in a sort payload.
Common situations: Stale UI state after a notebook was removed via a different device or sync; an external API client using a hardcoded or cached notebook ID that no longer exists; race condition where a notebook is deleted between the UI loading the tree and the user reordering it.
Related errors
- document [%s] not found in opened and unlocked notebooks
- duplicate notebook ID [%s]
- duplicate document ID [%s]
- block [%s] is not a sortable document
- notebook [%s] not found for document [%s]
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/9b0b0ed4e96471e8.
Report an issue: GitHub.