{"record":{"id":"41a5589cf41e9854","repo":"siyuan-note/siyuan","slug":"notebook-s-not-found-for-document-s","errorCode":null,"errorMessage":"notebook [%s] not found for document [%s]","messagePattern":"notebook \\[(.+?)\\] not found for document \\[(.+?)\\]","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/file.go","lineNumber":2942,"sourceCode":"\tdocIDs := map[string]struct{}{}\n\tfor _, item := range docSorts {\n\t\tif nil == item {\n\t\t\treturn ret, errors.New(\"document sort item must not be nil\")\n\t\t}\n\t\tif _, ok := docIDs[item.ID]; ok {\n\t\t\treturn ret, fmt.Errorf(\"duplicate document ID [%s]\", item.ID)\n\t\t}\n\t\tdocIDs[item.ID] = struct{}{}\n\n\t\tbt := treenode.GetBlockTree(item.ID)\n\t\tif nil == bt || nil == openedBoxes[bt.BoxID] {\n\t\t\treturn ret, fmt.Errorf(\"document [%s] not found in opened and unlocked notebooks\", item.ID)\n\t\t}\n\t\tif bt.ID != bt.RootID || \"d\" != bt.Type || IsBoxDoc(bt.BoxID, bt.RootID) {\n\t\t\treturn ret, fmt.Errorf(\"block [%s] is not a sortable document\", item.ID)\n\t\t}\n\t\tif nil == boxes[bt.BoxID] {\n\t\t\treturn ret, fmt.Errorf(\"notebook [%s] not found for document [%s]\", bt.BoxID, item.ID)\n\t\t}\n\t\tdocPlans = append(docPlans, &docSortPlan{item: item, boxID: bt.BoxID, parentPath: path.Dir(bt.Path)})\n\t}\n\n\tdocGroups := map[string]*docSortGroup{}\n\tfor _, plan := range docPlans {\n\t\tgroup := docGroups[plan.boxID]\n\t\tif nil == group {\n\t\t\tconfPath := filepath.Join(util.DataDir, plan.boxID, \".siyuan\", \"sort.json\")\n\t\t\tfullSortIDs, readErr := readSortConfMap(confPath)\n\t\t\tif readErr != nil {\n\t\t\t\treturn ret, readErr\n\t\t\t}\n\t\t\tgroup = &docSortGroup{\n\t\t\t\tfullSortIDs: fullSortIDs,\n\t\t\t\tchanged:     map[string]int{},\n\t\t\t\tparentSorts: map[string]map[string]int{},\n\t\t\t}","sourceCodeStart":2924,"sourceCodeEnd":2960,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/model/file.go#L2924-L2960","documentation":"Thrown during document-tree sorting (DocSort / ReorderDocTree path) after resolving each requested item to a block tree entry. The block exists and is a valid root document, but its notebook (box) cannot be found in the currently opened notebook set, so the sort plan cannot be built. The kernel refuses to sort documents whose parent notebook is closed, removed, or otherwise absent from Conf.Box.","triggerScenarios":"Calling the doc sorting API (e.g. /api/filetree/docSort or ReorderDocTree) with a document ID whose bt.BoxID is not among the currently opened notebooks (nil == boxes[bt.BoxID]). Happens when the notebook was closed, renamed, or removed between client-side listing and the sort call.","commonSituations":"Stale client state: UI still holds document IDs from a notebook that was closed or deleted in another window; syncing removed a notebook; a script passes IDs collected earlier against a fresh kernel instance with fewer notebooks open.","solutions":["Re-open the notebook containing the document (Conf.Box / notebook list API) and retry the sort","Re-fetch the current document list so the IDs passed to the sort API are fresh","Verify the notebook still exists in the workspace data directory and was not renamed/deleted","Filter the sort request to drop documents whose notebooks are not currently opened"],"exampleFix":"// before\napi.post('/api/filetree/docSort', {ids: staleIDs})\n// after\nconst opened = (await api.post('/api/notebook/lsNotebooks')).data.notebooks\nconst valid = staleIDs.filter(id => opened.some(nb => nb.id === boxOf(id)))\napi.post('/api/filetree/docSort', {ids: valid})","handlingStrategy":"validation","validationCode":"// Go-style caller check before sorting\nconst nb = (await api.post('/api/notebook/lsNotebooks')).data.notebooks.find(n => n.id === boxID)\nif (!nb) throw new Error(`notebook ${boxID} is not opened`)","typeGuard":null,"tryCatchPattern":"try { await sortDocs(ids) } catch (e) { if (String(e.msg).includes('not found for document')) { await refreshNotebookList(); retry(); } else { throw e } }","preventionTips":["Re-fetch the notebook list before any batch document operation","Treat document IDs as ephemeral; never persist them across sessions","Listen for notebook close/delete push events and invalidate cached ID sets"],"tags":["notebook","sorting","document-tree","stale-reference"],"backgroundTag":"entity-not-found","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}