siyuan-note/siyuan · error
notebook sort item must not be nil
Error message
notebook sort item must not be nil
What it means
SetFileTreeSort builds notebookSortPlan entries from the request's notebookSorts array and rejects a nil element outright. A null entry in the JSON array cannot carry an ID or sort weight, so the entire batch sort fails fast with this error before any file is moved.
Source
Thrown at kernel/model/file.go:2885
}
FlushTxQueue()
fileTreeSortLock.Lock()
defer fileTreeSortLock.Unlock()
boxes := map[string]*Box{}
for _, box := range Conf.GetBoxes() {
boxes[box.ID] = box
}
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")View on GitHub (pinned to 8641553a1f)
Solutions
- Inspect the request payload and remove null entries from the notebookSorts array before sending.
- Fix the client code that constructs the array to filter out undefined/null values (e.g. arr.filter(Boolean)).
- If a notebook was deleted, drop it from the sort list instead of sending a placeholder null.
Example fix
// before
fetchPost("/api/filetree/setFileTreeSort", {notebookSorts: [ ...items, removedNotebook ]})
// after
const items = [...items, removedNotebook].filter(Boolean);
fetchPost("/api/filetree/setFileTreeSort", {notebookSorts: items}) Defensive patterns
Strategy: validation
Validate before calling
if (notebookSorts.some(i => i == null)) {
throw new Error("notebookSorts contains null entries");
} Type guard
const isValidItem = (i) => i != null && typeof i.id === "string" && i.id.length > 0 && typeof i.sort === "number";
Try / catch
try {
await api.setFileTreeSort({notebookSorts});
} catch (e) {
if (String(e).includes("must not be nil")) {
return api.setFileTreeSort({notebookSorts: notebookSorts.filter(Boolean)});
}
throw e;
} Prevention
- Always filter arrays with .filter(Boolean) before serializing the sort payload
- Avoid building arrays with sparse holes (use splice or explicit removal)
- Validate payload items have id and sort fields before sending
When it happens
Trigger: Posting to the file-tree sort API a notebookSorts array containing a JSON null element, e.g. [{"id":"20240101120000-abc","sort":1},null], usually from a client-side array construction bug.
Common situations: Plugin or script building the sort payload by pushing undefined/null items (e.g. array built with holes, JSON.stringify of [undefined]); deserialization of sparse arrays from storage.
Related errors
- document sort item must not be nil
- duplicate notebook ID [%s]
- target ID [%s] is not in the current order
- source ID [%s] is not in the current order
- attribute view custom color must not be null
AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11).
Data as JSON: /api/errors/adeb179a185d798d.
Report an issue: GitHub.