siyuan-note/siyuan · error

notebook [ ] not found

Error message

notebook [%s] not found

What it means

saveNotebookCustomOrder persists a user's custom notebook sort order by looking up each requested ID in the provided boxes map. This error means an ID in orderedIDs does not correspond to any currently loaded notebook, so reordering is aborted (with rollback of already-written sorts by callers).

Solutions

  1. Re-fetch the current notebook list and retry the reorder using only IDs from that list
  2. Verify the notebook still exists in the workspace data/ directory and is open
  3. Remove stale IDs from the ordered list before calling ChangeBoxSort/ReorderNotebooks
  4. Avoid concurrent reorders from multiple windows/sessions

Example fix

// before
ids := []string{"20240101120000-abcdefg", "stale-id"}
ReorderNotebooks(ids)
// after
ids = filterExistingNotebooks(ids) // keep only IDs from current ListNotebooks()
ReorderNotebooks(ids)
Defensive patterns

Strategy: validation

Validate before calling

// Go: keep only IDs of currently open notebooks
valid := []string{}
for _, id := range orderedIDs {
    if boxes[id] != nil {
        valid = append(valid, id)
    }
}

Try / catch

if err := ReorderNotebooks(ids); err != nil {
    if strings.Contains(err.Error(), "not found") {
        ids = refreshAndFilterIDs(ids) // re-list notebooks and retry once
    }
}

Prevention

When it happens

Trigger: Calling ChangeBoxSort or ReorderNotebooks with an ordered ID list containing a notebook ID that is closed, already deleted, renamed on disk, or was never opened in this session; also hit in race conditions where a notebook is removed between listing and reordering.

Common situations: Two windows reordering notebooks concurrently; a client sending a stale notebook list after another session deleted the notebook; scripts hitting the reorder API with hardcoded IDs after notebooks were recreated with new IDs.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19). Data as JSON: /api/errors/2907c54d8631ac9a. Report an issue: GitHub.

Appendix: source

Thrown at kernel/model/box.go:1118

	requestedIndex := 0
	for _, id := range currentIDs {
		if _, requested := requestedSet[id]; requested {
			ret = append(ret, validRequestedIDs[requestedIndex])
			requestedIndex++
		} else {
			ret = append(ret, id)
		}
	}
	return
}

func saveNotebookCustomOrder(boxes map[string]*Box, orderedIDs []string) error {
	oldSorts := map[string]int{}
	writtenIDs := []string{}
	for i, id := range orderedIDs {
		box := boxes[id]
		if nil == box {
			return fmt.Errorf("notebook [%s] not found", id)
		}
		boxConf := box.GetConf()
		oldSorts[id] = boxConf.Sort
		newSort := i + 1
		if boxConf.Sort == newSort {
			continue
		}
		boxConf.Sort = newSort
		if err := box.SaveConf(boxConf); nil != err {
			for _, writtenID := range writtenIDs {
				writtenBox := boxes[writtenID]
				writtenConf := writtenBox.GetConf()
				writtenConf.Sort = oldSorts[writtenID]
				if rollbackErr := writtenBox.SaveConf(writtenConf); nil != rollbackErr {
					logging.LogErrorf("rollback notebook [%s] sort failed: %s", writtenID, rollbackErr)
				}
			}
			return err

View on GitHub (pinned to 9f775e8a12)