{"record":{"id":"08e7fcef22567d33","repo":"siyuan-note/siyuan","slug":"conf-language-0-notebook-not-found","errorCode":null,"errorMessage":"Conf.Language(0) (notebook not found)","messagePattern":"Conf\\.Language\\(0\\) \\(notebook not found\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/file.go","lineNumber":414,"sourceCode":"\t\t\tret.WriteRune('\\\\')\n\t\t}\n\t\tret.WriteRune(r)\n\t}\n\treturn ret.String()\n}\n\ntype FileInfo struct {\n\tpath  string\n\tname  string\n\tsize  int64\n\tisdir bool\n}\n\n// ResolveDocTreeSortMode 按当前父文档、最近祖先文档、笔记本和全局配置的顺序解析子文档排序方式。\nfunc ResolveDocTreeSortMode(boxID, listPath string) (sortMode int, err error) {\n\tbox := Conf.Box(boxID)\n\tif nil == box {\n\t\treturn 0, errors.New(Conf.Language(0))\n\t}\n\n\tnormalized, err := box.validateBoxPath(listPath)\n\tif nil != err {\n\t\treturn 0, err\n\t}\n\tnormalized = filepath.ToSlash(normalized)\n\tif \"\" != normalized {\n\t\tdocPath := \"/\" + strings.TrimPrefix(path.Clean(\"/\"+normalized), \"/\")\n\t\tif !strings.HasSuffix(docPath, \".sy\") {\n\t\t\tdocPath += \".sy\"\n\t\t}\n\n\t\tfor \"\" != docPath && !IsBoxDocPath(boxID, docPath) {\n\t\t\t// 仅探测确实存在的文档，避免将同步中的临时缺失误判为损坏数据。\n\t\t\tif box.Exist(docPath) {\n\t\t\t\tif declared := docSortModeFromIAL(box.docIAL(docPath)); nil != declared {\n\t\t\t\t\treturn *declared, nil","sourceCodeStart":396,"sourceCodeEnd":432,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/8641553a1f07374001902d3ce773285db1292b2d/kernel/model/file.go#L396-L432","documentation":"ResolveDocTreeSortMode resolves the sort mode for a document list by walking parent doc, nearest ancestor doc, notebook, and global config. The very first step looks up Conf.Box(boxID); when no notebook with that ID exists in the current workspace it returns Conf.Language(0) ('Query notebook failed').","triggerScenarios":"Calling ResolveDocTreeSortMode (directly or via ListDocTree/SetDocSortMode) with a boxID that is not an open notebook: stale ID after notebook removal, closed notebook, or typo'd ID from a client.","commonSituations":"Frontend holding a cached notebook ID after the notebook was deleted or its path removed; sync restoring a tree referencing a removed notebook; API scripts iterating IDs from outdated listings.","solutions":["Refresh the notebook list (Conf.Box / /api/notebook/lsNotebooks) and use a current box ID.","Reopen or re-add the missing notebook to the workspace before setting/querying sort mode.","Validate boxID is non-empty and exists before calling the sort-mode API from scripts."],"exampleFix":"// before\nsetDocSortMode(staleBoxID, path, sortMode);\n// after\nconst boxes = await fetchPost('/api/notebook/lsNotebooks');\nif (boxes.some(b => b.id === boxId)) setDocSortMode(boxId, path, sortMode);","handlingStrategy":"validation","validationCode":"const boxes = (await fetchPost('/api/notebook/lsNotebooks')).data.notebooks;\nif (!boxes.some(b => b.id === boxId)) throw new Error('notebook not open: ' + boxId);","typeGuard":null,"tryCatchPattern":"try {\n  await setDocSortMode(boxId, path, mode);\n} catch (e) {\n  await refreshNotebookList(); // recover by reloading current notebook IDs\n}","preventionTips":["Always resolve notebook IDs from a fresh lsNotebooks call, never from long-lived caches","Handle notebook close/delete events by invalidating stored box IDs","Check for empty boxID before invoking sort-mode APIs"],"tags":["notebook","not-found","sort-mode"],"backgroundTag":"resource-not-found","analyzedSha":"8641553a1f07374001902d3ce773285db1292b2d","analyzedAt":"2026-09-11T16:08:28.414Z","contentChangedAt":"2026-09-11T16:08:28.414Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}