siyuan-note/siyuan · error
query database-bound blocks in notebook
Error message
query database-bound blocks in notebook [%s] failed: %w
What it means
Before deleting the notebook directory, RemoveBox calls collectBoxDeletedAttributeViewBlocks, which queries the SQLite index for database (attribute-view) blocks bound to the notebook so bound rows can be cleaned up after deletion. If that query fails, removal aborts with "query database-bound blocks in notebook [%s] failed: %w" wrapping the underlying SQL error. The notebook is left intact because the query must succeed before the directory is removed.
Solutions
- Inspect the wrapped (%w) inner error in logs to identify the SQL failure; fix that root cause first
- Ensure no second kernel instance is using the same workspace (siyuan.db file lock)
- If the database is corrupted, close the kernel and run SQLite integrity/recovery (PRAGMA integrity_check; .recover) on data/index/siyuan.db, then rebuild the index (Ctrl+F5 / 'Rebuild Index')
- After the DB is healthy, retry the notebook removal — the pre-delete collection is re-run on each attempt
Defensive patterns
Strategy: try-catch
Validate before calling
// pre-check DB readability before attempting removal
rows, err := query("SELECT count(*) FROM blocks WHERE box = ?", boxID)
if err != nil { return fmt.Errorf("index db unreadable for %s: %w", boxID, err) } Try / catch
if err := removeNotebook(boxID); err != nil {
var qe *fmt.WrapError // unwrap the %w chain
if strings.HasPrefix(err.Error(), "query database-bound blocks") {
// do NOT retry blindly: repair/rebuild siyuan.db first, then retry
rebuildIndex()
return removeNotebook(boxID)
}
return err
} Prevention
- Avoid running multiple kernel instances on the same workspace
- Run on a filesystem/journal setup that survives power loss, and back up data/index/siyuan.db
- Rebuild the index after any abnormal kernel termination before doing destructive notebook operations
- Monitor disk-full conditions: failed index transactions are a common root cause
When it happens
Trigger: sql.QueryBoundBlockAVIDsInBox failing while collecting custom-av bindings — usually when siyuan.db is corrupted, locked by another writer, or the index queue is in a bad state; it can also surface after a crashed index transaction left the blocks tables unreadable for that box.
Common situations: SQLite database corruption after a hard power-off or disk-full during indexing; database file locked by a second SiYuan instance pointed at the same workspace; version-upgrade migrations partially applied; antivirus locking siyuan.db on Windows.
Understand the failure class
Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.
Related errors
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/c4d6c8d9bb643c1c.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/model/mount.go:286
if !ast.IsNodeIDPattern(boxID) {
return errors.New("invalid notebook ID")
}
if _, loaded := boxLock.LoadOrStore(boxID, true); loaded {
err = errors.New(Conf.language(239))
return
}
defer boxLock.Delete(boxID)
if util.IsReservedFilename(boxID) {
return fmt.Errorf("can not remove [%s] caused by it is a reserved file", boxID)
}
FlushTxQueue()
sql.FlushQueue()
// 索引和笔记本目录删除后无法再读取 custom-avs,需提前收集;实际删除成功后再清理绑定行。
deletedAttrViewBlockIDs, err := collectBoxDeletedAttributeViewBlocks(boxID)
if nil != err {
return fmt.Errorf("query database-bound blocks in notebook [%s] failed: %w", boxID, err)
}
isUserGuide := IsUserGuide(boxID)
localPath := filepath.Join(util.DataDir, boxID)
if !filelock.IsExist(localPath) {
removeHPathRefreshBox(boxID)
forgetRuntimeNormalBox(boxID)
removeMasterPasswordMigrationBox(boxID)
return
}
if !gulu.File.IsDir(localPath) {
return fmt.Errorf("can not remove [%s] caused by it is not a dir", boxID)
}
// 删目录前固定加密状态,确保后续历史、资源和索引清理始终使用同一个安全边界。
isEncrypted := IsEncryptedBox(boxID)
if !isUserGuide {
if err = EnsureAssetPrefixLocal(localPath); err != nil {
returnView on GitHub (pinned to 9f775e8a12)