siyuan-note/siyuan · critical
block rowid not found after insert
Error message
block rowid not found after insert: %s
What it means
After bulk-inserting blocks into the blocks/FTS tables, insertBlocks0 re-queries rowids for each inserted block ID to build FTS rows. If a freshly inserted ID is missing from the returned rowid map, the kernel treats it as a broken invariant and aborts the FTS population to avoid misaligned FTS arguments. The code comments this as 'theoretically impossible' defensive handling.
Solutions
- Retry the insert operation; the error aborts before FTS misalignment so re-running usually succeeds
- Check for concurrent writers to the same database (only one kernel should own the workspace)
- Verify database integrity (sqlite3 'PRAGMA integrity_check') and rebuild the index
- Inspect the reported block ID for duplicates or anomalies in the source document
Defensive patterns
Strategy: retry
Try / catch
err := insertBlocks(tx, blocks)
if err != nil && strings.Contains(err.Error(), "block rowid not found after insert") {
return retryInsert(tx, blocks) // abort happened before FTS misalignment; safe to retry
} Prevention
- Avoid multiple concurrent writers to the same workspace DB
- Rebuild the index if errors persist (indicates DB anomaly)
- Never write to siyuan.db with external tools while the kernel is running
When it happens
Trigger: insertBlocks bulk-insert completes but the subsequent rowid lookup fails to return a row for a block ID — e.g. due to concurrent writes, trigger/replica anomalies, ID collisions, or a partial insert failure not surfaced earlier.
Common situations: Concurrent document editing racing with bulk insert; database corruption or unusual sync states; custom tooling writing directly to siyuan.db and deleting rows mid-flight.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- attribute view rich text style entity sentinel was not…
- attribute view [ ] template plan not found
- block not found
- clone attribute view
- copied attribute view
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/6ff57a4f534ae201.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/sql/upsert.go:143
hashBuf.WriteString("blocks")
evtHash := fmt.Sprintf("%x", sha256.Sum256(hashBuf.Bytes()))[:7]
// 使用下面的 EvtSQLInsertBlocksFTS 就可以了
//eventbus.Publish(eventbus.EvtSQLInsertBlocks, context, current, total, len(bulk), evtHash)
// external content 模式下,FTS 行必须使用 blocks 的 rowid。刚插入的 blocks 行在同一事务内可见,
// 这里按 id 反查 rowid,再用与 bulk 顺序对齐的 rowid 拼装 FTS 写入参数。
blockRowIDs, err := queryBlockRowIDsTx(tx, bulk)
if err != nil {
return
}
ftsValueStrings := make([]string, 0, len(bulk))
ftsValueArgs := make([]any, 0, len(bulk)*strings.Count(BlocksFTSPlaceholder, "?"))
for _, b := range bulk {
rowID, ok := blockRowIDs[b.ID]
if !ok {
// 理论上不会发生(刚插入即反查),防御性处理避免错位
logging.LogErrorf("query block rowid failed after insert: id=%s not found", b.ID)
err = fmt.Errorf("block rowid not found after insert: %s", b.ID)
return
}
ftsValueStrings = append(ftsValueStrings, BlocksFTSPlaceholder)
ftsValueArgs = append(ftsValueArgs, rowID)
ftsValueArgs = append(ftsValueArgs, any(b.ID))
ftsValueArgs = append(ftsValueArgs, any(b.ParentID))
ftsValueArgs = append(ftsValueArgs, any(b.RootID))
ftsValueArgs = append(ftsValueArgs, any(b.Hash))
ftsValueArgs = append(ftsValueArgs, any(b.Box))
ftsValueArgs = append(ftsValueArgs, any(b.Path))
ftsValueArgs = append(ftsValueArgs, any(b.HPath))
ftsValueArgs = append(ftsValueArgs, any(b.Name))
ftsValueArgs = append(ftsValueArgs, any(b.Alias))
ftsValueArgs = append(ftsValueArgs, any(b.Memo))
ftsValueArgs = append(ftsValueArgs, any(b.Tag))
ftsValueArgs = append(ftsValueArgs, any(b.Content))
ftsValueArgs = append(ftsValueArgs, any(b.FContent))
ftsValueArgs = append(ftsValueArgs, any(b.Markdown))View on GitHub (pinned to 9f775e8a12)