{"record":{"id":"22955dc0b8318d49","repo":"siyuan-note/siyuan","slug":"database-entry-s-already-exists","errorCode":null,"errorMessage":"database entry [%s] already exists","messagePattern":"database entry \\[(.+?)\\] already exists","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/attribute_view_items.go","lineNumber":294,"sourceCode":"\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (tx *Transaction) restoreAttributeViewItems(op *Operation) error {\n\tstate := op.attributeViewItems\n\tif !tx.isReplay || op.AvID != state.AvID {\n\t\treturn fmt.Errorf(\"invalid database entry replay\")\n\t}\n\tcurrent, err := tx.readAttributeViewItems(state)\n\tif err != nil {\n\t\treturn err\n\t}\n\tfor _, kv := range current.KeyValues {\n\t\tfor _, value := range kv.Values {\n\t\t\tif slices.Contains(state.ItemIDs, value.BlockID) {\n\t\t\t\treturn fmt.Errorf(\"database entry [%s] already exists\", value.BlockID)\n\t\t\t}\n\t\t}\n\t}\n\tif err = validateAttributeViewItemKeys(current, state); err != nil {\n\t\treturn err\n\t}\n\tfor _, kv := range state.Keys {\n\t\tfor _, value := range kv.Values {\n\t\t\tif value.Type != av.KeyTypeBlock || value.IsDetached || value.Block == nil {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\ttree, loadErr := tx.loadTree(value.Block.ID)\n\t\t\tif loadErr != nil {\n\t\t\t\treturn loadErr\n\t\t\t}\n\t\t\tif err = validateAttributeViewBinding(state.AvID, tree); err != nil {\n\t\t\t\treturn err\n\t\t\t}","sourceCodeStart":276,"sourceCodeEnd":312,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/model/attribute_view_items.go#L276-L312","documentation":"During transaction replay (undo/redo of an 'insert database entries' operation), the kernel re-applies a snapshot of previously inserted rows. Before restoring, it scans the current attribute view for any value whose BlockID is already in the snapshot's item list; if one exists, restoring would duplicate the row, so it aborts with this error. It is an internal consistency guard ensuring idempotent replay of entry insertion.","triggerScenarios":"Replaying a doInsertAttrViewBlock operation whose target rows were re-created (same BlockIDs already present in the attribute view) between the original deletion and the replay — e.g. an undo/redo sequence that re-inserts entries that were later re-added with the same block IDs.","commonSituations":"Undo/redo history interleaved with other edits; rows restored by sync or another transaction before the replay runs; a plugin or script inserting rows with explicit block IDs that collide with the replayed snapshot.","solutions":["Check the current database for rows with those block IDs and remove the duplicates before retrying the transaction","Clear the conflicting transaction history (undo the intermediate operations) so replay no longer collides","Avoid inserting rows bound to existing block IDs that already appear in the same database; let the kernel generate fresh item IDs","If triggered by sync, resolve the sync conflict so both sides agree on which rows exist"],"exampleFix":"// before: re-inserting rows whose block IDs still exist\nattrsView.InsertRows(existingBlockIDs...)\n// after: only insert IDs not already present in the database\nids := filter(existingBlockIDs, func(id string) bool { return current.GetBlockValue(id) == nil })\nattrsView.InsertRows(ids...)","handlingStrategy":"try-catch","validationCode":"// client-side: ensure target IDs are not already rows in the database\nconst exists = await getAttrView(avID);\nconst dup = exists.keyValues.flatMap(kv => kv.values.map(v => v.blockID)).filter(id => itemIDs.includes(id));\nif (dup.length) throw new Error(`rows already present: ${dup.join(',')}`);","typeGuard":null,"tryCatchPattern":"try { await insertAttrViewBlock(avID, blockID, items); } catch (e) { if (/database entry \\[.+\\] already exists/.test(e.message)) { await removeDuplicateRows(avID, itemIDs); retry(); } else throw e; }","preventionTips":["Do not re-insert rows with block IDs that may already exist in the same database","Minimize interleaved undo/redo edits between delete and re-insert of the same rows","Resolve sync conflicts promptly so replay state stays consistent"],"tags":["database","transaction-replay","duplicate-entry","attribute-view"],"backgroundTag":"file-already-exists","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"}