{"record":{"id":"6ff57a4f534ae201","repo":"siyuan-note/siyuan","slug":"block-rowid-not-found-after-insert-s","errorCode":null,"errorMessage":"block rowid not found after insert: %s","messagePattern":"block rowid not found after insert: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"kernel/sql/upsert.go","lineNumber":143,"sourceCode":"\thashBuf.WriteString(\"blocks\")\n\tevtHash := fmt.Sprintf(\"%x\", sha256.Sum256(hashBuf.Bytes()))[:7]\n\t// 使用下面的 EvtSQLInsertBlocksFTS 就可以了\n\t//eventbus.Publish(eventbus.EvtSQLInsertBlocks, context, current, total, len(bulk), evtHash)\n\n\t// external content 模式下，FTS 行必须使用 blocks 的 rowid。刚插入的 blocks 行在同一事务内可见，\n\t// 这里按 id 反查 rowid，再用与 bulk 顺序对齐的 rowid 拼装 FTS 写入参数。\n\tblockRowIDs, err := queryBlockRowIDsTx(tx, bulk)\n\tif err != nil {\n\t\treturn\n\t}\n\tftsValueStrings := make([]string, 0, len(bulk))\n\tftsValueArgs := make([]any, 0, len(bulk)*strings.Count(BlocksFTSPlaceholder, \"?\"))\n\tfor _, b := range bulk {\n\t\trowID, ok := blockRowIDs[b.ID]\n\t\tif !ok {\n\t\t\t// 理论上不会发生（刚插入即反查），防御性处理避免错位\n\t\t\tlogging.LogErrorf(\"query block rowid failed after insert: id=%s not found\", b.ID)\n\t\t\terr = fmt.Errorf(\"block rowid not found after insert: %s\", b.ID)\n\t\t\treturn\n\t\t}\n\t\tftsValueStrings = append(ftsValueStrings, BlocksFTSPlaceholder)\n\t\tftsValueArgs = append(ftsValueArgs, rowID)\n\t\tftsValueArgs = append(ftsValueArgs, any(b.ID))\n\t\tftsValueArgs = append(ftsValueArgs, any(b.ParentID))\n\t\tftsValueArgs = append(ftsValueArgs, any(b.RootID))\n\t\tftsValueArgs = append(ftsValueArgs, any(b.Hash))\n\t\tftsValueArgs = append(ftsValueArgs, any(b.Box))\n\t\tftsValueArgs = append(ftsValueArgs, any(b.Path))\n\t\tftsValueArgs = append(ftsValueArgs, any(b.HPath))\n\t\tftsValueArgs = append(ftsValueArgs, any(b.Name))\n\t\tftsValueArgs = append(ftsValueArgs, any(b.Alias))\n\t\tftsValueArgs = append(ftsValueArgs, any(b.Memo))\n\t\tftsValueArgs = append(ftsValueArgs, any(b.Tag))\n\t\tftsValueArgs = append(ftsValueArgs, any(b.Content))\n\t\tftsValueArgs = append(ftsValueArgs, any(b.FContent))\n\t\tftsValueArgs = append(ftsValueArgs, any(b.Markdown))","sourceCodeStart":125,"sourceCodeEnd":161,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/sql/upsert.go#L125-L161","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"err := insertBlocks(tx, blocks)\nif err != nil && strings.Contains(err.Error(), \"block rowid not found after insert\") {\n    return retryInsert(tx, blocks) // abort happened before FTS misalignment; safe to retry\n}","preventionTips":["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"],"tags":["sql","fts","indexing","invariant"],"backgroundTag":"internal-invariant-violation","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}