siyuan-note/siyuan · error

encrypted blocktree db not opened for box

Error message

encrypted blocktree db not opened for box 

What it means

queryForBox routes block-tree SQL queries to a per-box encrypted database when one is open. If the box is marked encrypted (IsEncryptedBoxFn) but its encrypted blocktree DB was never opened/attached, the query cannot safely fall back to the plaintext DB (that would bypass authentication), so it fails with this error naming the box.

Solutions

  1. Open/unlock the encrypted notebook first so its encrypted blocktree DB is attached, then retry the query.
  2. Check the box ID spelling/validity; an incorrect box ID can be wrongly classified as encrypted.
  3. If running embeded code, ensure IsEncryptedBoxFn state matches actual opened DBs — re-open the box DB instead of querying.
Defensive patterns

Strategy: try-catch

Try / catch

rows, err := queryForBox(box, stmt, args...)
if err != nil && strings.HasPrefix(err.Error(), "encrypted blocktree db not opened") {
    // unlock/open the encrypted box DB, then retry once
}

Prevention

When it happens

Trigger: Calling GetBlockTreesByBoxID, GetRootBlockIDsByBoxID, GetBlockTreeRootsByHPath, GetBlockTreesByTypeInBox, GetBlockTreesByPathPrefix, or RemoveBlockTreesByBoxID for an encrypted box whose encrypted blocktree DB handle is not registered via getEncryptedBlockTreeDB.

Common situations: Querying an encrypted notebook before its lease/key was unlocked (e.g. at boot, before opening the box), or after the encrypted DB was closed; calling kernel APIs directly for an encrypted box without going through the unlock flow.

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/11d788467cb2e1da. Report an issue: GitHub.

Appendix: source

Thrown at kernel/treenode/blocktree.go:1064

	}
	if err = ensureHPathIndexes(boxDB); err != nil {
		return
	}
	if err = cleanupInvalidBlockTrees(boxDB); err != nil {
		return
	}
	return
}

// --- box-scoped wrapper(加密笔记本用独立 db,否则用全局 db)---
// 加密笔记本未解锁(db 未打开)时 fail-closed:绝不回退全局库,避免加密笔记本块树操作污染全局 blocktree.db。

func queryForBox(box, stmt string, args ...any) (*sql.Rows, error) {
	if boxDB := getEncryptedBlockTreeDB(box); boxDB != nil {
		return boxDB.Query(stmt, args...)
	}
	if IsEncryptedBoxFn != nil && IsEncryptedBoxFn(box) {
		return nil, errors.New("encrypted blocktree db not opened for box " + box)
	}
	return query(stmt, args...)
}

func queryRowForBox(box, stmt string, args ...any) *sql.Row {
	if boxDB := getEncryptedBlockTreeDB(box); boxDB != nil {
		return boxDB.QueryRow(stmt, args...)
	}
	if IsEncryptedBoxFn != nil && IsEncryptedBoxFn(box) {
		return nil
	}
	return queryRow(stmt, args...)
}

func execForBox(box, stmt string, args ...any) (sql.Result, error) {
	if boxDB := getEncryptedBlockTreeDB(box); boxDB != nil {
		return boxDB.Exec(stmt, args...)
	}

View on GitHub (pinned to 9f775e8a12)