{"record":{"id":"fc5103da5c50f084","repo":"siyuan-note/siyuan","slug":"query-notebook-failed-fc5103","errorCode":null,"errorMessage":"Query notebook failed","messagePattern":"Query notebook failed","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/file.go","lineNumber":405,"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":387,"sourceCodeEnd":423,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/afa823b6b4e4f183511e0bc0a3be93caa94c7c97/kernel/model/file.go#L387-L423","documentation":"ResolveDocTreeSortMode is called by the listDocsByPath handler (POST /api/filetree/listDocsByPath, kernel/api/filetree.go:1317) whenever the request leaves sort unassigned; it resolves the effective sort mode from doc/notebook/global config. Conf.Box(boxID) returned nil — the notebook ID is unknown to the kernel — so the localized \"Query notebook failed\" (Conf.Language(0)) is returned and nothing is listed.","triggerScenarios":"POST /api/filetree/listDocsByPath (or listDocTree) with a notebook/box ID that is closed, deleted, or malformed; also when the notebook is closed between the UI load and the request.","commonSituations":"Stale box IDs cached by a plugin; notebook closed or removed mid-session; API called before the workspace finished loading; copy-pasted wrong ID.","solutions":["Fetch fresh IDs via POST /api/notebook/lsNotebooks and use a returned id","Reopen the closed notebook (POST /api/notebook/openNotebook) before listing","Re-issue the listing after notebook/workspace state changes settle"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if model.Conf.Box(boxID) == nil {\n\treturn fmt.Errorf(\"notebook %s is not open or does not exist\", boxID)\n}\nsortMode, err := model.ResolveDocTreeSortMode(boxID, listPath)","typeGuard":"func isNotebookListable(boxID string) bool {\n\treturn model.Conf.Box(boxID) != nil\n}","tryCatchPattern":null,"preventionTips":["Refresh notebook IDs after open/close events","Never persist box IDs across sessions without revalidation"],"tags":["notebook","filetree","validation","not-found"],"backgroundTag":"notebook-not-found","analyzedSha":"afa823b6b4e4f183511e0bc0a3be93caa94c7c97","analyzedAt":"2026-08-18T17:04:10.865Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}