siyuan-note/siyuan · warning

block tree database is unavailable

Error message

block tree database is unavailable

What it means

errBlockTreeDBUnavailable signals that the block tree database (blocktree.db) has not been initialized or is not open, so tree lookup/count operations cannot run. Accessors such as CountTrees, CountBlocks, ExistBlockTree, GetBlockTree, scanQueryRow, and GetBlockTreeInExactBox return it instead of panicking; several count helpers deliberately swallow it and return zero (see blocktree.go:237/249). It is a sentinel error for 'the index DB is not ready'.

Solutions

  1. Ensure the kernel/workspace index is fully initialized before querying; wait for boot/index-ready signal
  2. Trigger a tree index rebuild if blocktree.db is missing or corrupt
  3. In callers, treat this sentinel like sql.ErrNoRows (return zero/default) when a default is acceptable, or retry after init

Example fix

// before
bt := treenode.GetBlockTree(id) // nil + sentinel swallowed during boot
// after
if !indexReady() {
    time.Sleep(500 * time.Millisecond) // or wait on init signal
}
bt := treenode.GetBlockTree(id)
Defensive patterns

Strategy: fallback

Validate before calling

if (!kernelBooted()) await waitForKernelBoot();

Try / catch

bt := treenode.GetBlockTree(id)
if bt == nil {
    // treat as 'not found / index not ready', retry after init or rebuild index
}

Prevention

When it happens

Trigger: Calling GetBlockTree/CountBlocks etc. before initDatabase has completed (e.g. very early during kernel boot) or after the blocktree DB failed to open; querying from a context where the workspace index was never built.

Common situations: Race during startup where plugins query block trees before initialization finishes; blocktree.db locked or corrupt so opening failed; calling index APIs from tests without initializing the DB.

Related errors


AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19). Data as JSON: /api/errors/fb48dc705a1ab597. Report an issue: GitHub.

Appendix: source

Thrown at kernel/treenode/blocktree.go:52

	"github.com/88250/lute/parse"
	"github.com/siyuan-note/logging"
	"github.com/siyuan-note/siyuan/kernel/util"
)

type BlockTree struct {
	ID       string // 块 ID
	RootID   string // 根 ID
	ParentID string // 父 ID
	BoxID    string // 笔记本 ID
	Path     string // 文档数据路径
	HPath    string // 文档可读路径
	Updated  string // 更新时间
	Type     string // 类型
}

var (
	db                        *sql.DB
	errBlockTreeDBUnavailable = errors.New("block tree database is unavailable")

	initDatabaseLock = sync.RWMutex{}
)

func initDatabase(forceRebuild bool) {
	initDatabaseLock.Lock()
	defer initDatabaseLock.Unlock()

	initDBConnection()

	if !forceRebuild {
		if !gulu.File.IsExist(util.BlockTreeDBPath) {
			forceRebuild = true
		}
	}
	if !forceRebuild {
		// 校验块树表是否可用,避免因上次重建被中断导致数据库文件存在但表缺失
		var table string

View on GitHub (pinned to 9f775e8a12)