siyuan-note/siyuan · error
Query notebook failed
Error message
Query notebook failed
What it means
During the document-level assets search, getAssetAbsPath calls ListNotebooks(); failure returns the localized 'Query notebook failed' (Conf.Language(0)). The cause is workspace-level I/O or index trouble - the notebook listing under data/ could not be read - not a problem with the specific asset.
Solutions
- Verify the kernel process can read <workspace>/data and fix ownership/permissions
- Restart the kernel so the notebook list is rebuilt
- Move the workspace back to healthy local storage and reopen it
- If the volume reports errors, repair it before continuing
Defensive patterns
Strategy: retry
Validate before calling
if f, err := os.Open(util.DataDir); err != nil {
// data dir unreadable: fix permissions/mount before resolving assets
} else {
f.Close()
} Try / catch
On this error, retry the whole resolution once after confirming data/ is readable; persistent failure means an environment problem (disk, mount, permissions), not an asset problem.
Prevention
- Keep the workspace on local, healthy disks
- Avoid moving or unmounting the workspace while the kernel runs
- Run the kernel as the user who owns the workspace files
When it happens
Trigger: The kernel cannot read the data/ directory (permissions or ownership), the notebook index is corrupt, the disk or network share holding the workspace is failing, or the workspace was moved while the kernel was running.
Common situations: Workspace on a NAS/external drive that dropped; permissions changed by security software; workspace copied between machines under different user accounts.
Related errors
- 106
- can not open file, just support open folder only
- can not remove [ ] caused by it is not a dir
- Conf.Language(373)
- Conf.Language(387)
AI-assisted analysis of siyuan-note/siyuan@afa823b6b4 (2026-08-18).
Data as JSON: /api/errors/6ad0e193c39742c6.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/model/assets.go:1207
if rootEvalErr != nil {
return "", fmt.Errorf("resolve assets root [%s] failed: %w", assetsRoot, rootEvalErr)
}
if !gulu.File.IsSubPath(realAssetsRoot, realP) {
return "", fmt.Errorf("symlink [%s] resolves outside data/assets: [%s]", p, realP)
}
// 安全校验使用解析后的路径,返回原路径以便下游与 DataDir 保持同一路径形式
return p, nil
}
return p, nil
}
// 在文档同级 assets 文件夹下搜索
if !strings.HasPrefix(relativePath, "assets/") {
return "", nil
}
notebooks, err := ListNotebooks()
if err != nil {
return "", errors.New(Conf.Language(0))
}
for _, notebook := range notebooks {
if !includeEncrypted && IsEncryptedBox(notebook.ID) {
continue // 加密笔记本的资源不参与全局路径解析(孤岛,资源不跨边界)
}
notebookAbsPath := filepath.Join(util.DataDir, notebook.ID)
filelock.Walk(notebookAbsPath, func(path string, d fs.DirEntry, err error) error {
if isSkipFile(d.Name()) {
if d.IsDir() {
return filepath.SkipDir
}
return nil
}
if p := filepath.ToSlash(path); strings.HasSuffix(p, relativePath) {
if gulu.File.IsExist(path) {
absPath = path
return fs.SkipAll
}View on GitHub (pinned to afa823b6b4)