{"record":{"id":"6ad0e193c39742c6","repo":"siyuan-note/siyuan","slug":"query-notebook-failed","errorCode":null,"errorMessage":"Query notebook failed","messagePattern":"Query notebook failed","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/assets.go","lineNumber":1171,"sourceCode":"\t\t\tif rootEvalErr != nil {\n\t\t\t\treturn \"\", fmt.Errorf(\"resolve assets root [%s] failed: %w\", assetsRoot, rootEvalErr)\n\t\t\t}\n\t\t\tif !gulu.File.IsSubPath(realAssetsRoot, realP) {\n\t\t\t\treturn \"\", fmt.Errorf(\"symlink [%s] resolves outside data/assets: [%s]\", p, realP)\n\t\t\t}\n\t\t\t// 安全校验使用解析后的路径，返回原路径以便下游与 DataDir 保持同一路径形式\n\t\t\treturn p, nil\n\t\t}\n\t\treturn p, nil\n\t}\n\n\t// 在文档同级 assets 文件夹下搜索\n\tif !strings.HasPrefix(relativePath, \"assets/\") {\n\t\treturn \"\", nil\n\t}\n\tnotebooks, err := ListNotebooks()\n\tif err != nil {\n\t\treturn \"\", errors.New(Conf.Language(0))\n\t}\n\tfor _, notebook := range notebooks {\n\t\tif !includeEncrypted && IsEncryptedBox(notebook.ID) {\n\t\t\tcontinue // 加密笔记本的资源不参与全局路径解析（孤岛，资源不跨边界）\n\t\t}\n\t\tnotebookAbsPath := filepath.Join(util.DataDir, notebook.ID)\n\t\tfilelock.Walk(notebookAbsPath, func(path string, d fs.DirEntry, err error) error {\n\t\t\tif isSkipFile(d.Name()) {\n\t\t\t\tif d.IsDir() {\n\t\t\t\t\treturn filepath.SkipDir\n\t\t\t\t}\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\tif p := filepath.ToSlash(path); strings.HasSuffix(p, relativePath) {\n\t\t\t\tif gulu.File.IsExist(path) {\n\t\t\t\t\tabsPath = path\n\t\t\t\t\treturn fs.SkipAll\n\t\t\t\t}","sourceCodeStart":1153,"sourceCodeEnd":1189,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/kernel/model/assets.go#L1153-L1189","documentation":"Thrown by getAssetAbsPath (kernel/model/assets.go:1171) when model.ListNotebooks() returns an error during the document-colocated assets search. Conf.Language(0) renders as `Query notebook failed`. It is not about the asset itself but about the kernel's inability to enumerate notebooks (which it needs in order to walk each notebook for an asset whose suffix matches relativePath).","triggerScenarios":"Calling the global asset resolver for an `assets/...` path that is not found under `data/assets/`, forcing the fallback notebook walk, at a moment when ListNotebooks fails — typically because the notebook configuration/conf.json set cannot be read or parsed, or the underlying filesystem/lock is unavailable.","commonSituations":"Corrupted or unreadable notebook conf.json after a crash; filelock contention or a locked workspace; permissions preventing the kernel from reading the notebooks directory; a half-written conf.json during sync.","solutions":["Check the kernel logs for the underlying ListNotebooks error (it is wrapped/suppressed by Conf.Language(0) here).","Verify the notebooks directory and each `<boxID>/.siyuan/conf.json` are readable and valid JSON.","Release any stale filelock (`.siyuan.lock`) and ensure no other kernel process holds the workspace.","Fix permissions/ownership so the kernel process can read the notebooks directory, then retry."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Pre-flight notebook enumeration to surface the real underlying error.\nif _, err := model.ListNotebooks(); err != nil {\n    return fmt.Errorf(\"notebooks unavailable, cannot resolve asset: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"if _, err := model.GetAssetAbsPath(ref); err != nil && strings.Contains(err.Error(), \"Query notebook failed\") {\n    // ListNotebooks failed; check logs for the wrapped cause (corrupt conf.json / lock / perms)\n    logging.LogErrorf(\"notebook enumeration failed during asset resolve\")\n}","preventionTips":["Keep notebook conf.json files valid; back up before editing.","Avoid holding/stalling the workspace filelock from external processes.","Run the kernel under a user that can read the notebooks directory."],"tags":["assets","notebooks","filesystem","configuration","workspace"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}