{"record":{"id":"ca76b5907e0434d4","repo":"siyuan-note/siyuan","slug":"attribute-view-item-s-not-found","errorCode":null,"errorMessage":"attribute view item [%s] not found","messagePattern":"attribute view item \\[(.+?)\\] not found","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/attribute_view.go","lineNumber":1933,"sourceCode":"\t\treturn fmt.Errorf(\"invalid card cover source [%s]\", data.Source)\n\t}\n\tif nil != data.Position {\n\t\tif \"\" == data.Position.Image || 32*1024 < len(data.Position.Image) {\n\t\t\treturn errors.New(\"invalid card cover image\")\n\t\t}\n\t\tif math.IsNaN(data.Position.X) || math.IsInf(data.Position.X, 0) ||\n\t\t\tmath.IsNaN(data.Position.Y) || math.IsInf(data.Position.Y, 0) ||\n\t\t\tdata.Position.X < 0 || 100 < data.Position.X || data.Position.Y < 0 || 100 < data.Position.Y {\n\t\t\treturn fmt.Errorf(\"invalid card cover position [%v, %v]\", data.Position.X, data.Position.Y)\n\t\t}\n\t}\n\n\tattrView, err := av.ParseAttributeView(operation.AvID)\n\tif nil != err {\n\t\treturn\n\t}\n\tif nil == attrView.GetBlockValue(operation.RowID) {\n\t\treturn fmt.Errorf(\"attribute view item [%s] not found\", operation.RowID)\n\t}\n\tview, err := getAttrViewViewByBlockID(attrView, operation.BlockID)\n\tif nil != err {\n\t\treturn\n\t}\n\tif av.LayoutTypeGallery != view.LayoutType && av.LayoutTypeKanban != view.LayoutType {\n\t\treturn av.ErrWrongLayoutType\n\t}\n\tvar source string\n\tif av.LayoutTypeGallery == view.LayoutType {\n\t\tsource = av.CardCoverSource(view.Gallery.CoverFrom, view.Gallery.CoverFromAssetKeyID)\n\t} else {\n\t\tsource = av.CardCoverSource(view.Kanban.CoverFrom, view.Kanban.CoverFromAssetKeyID)\n\t}\n\tif data.Source != source {\n\t\treturn fmt.Errorf(\"card cover source [%s] does not match view [%s]\", data.Source, view.ID)\n\t}\n\tif keyID := av.CardCoverSourceAssetKeyID(data.Source); \"\" != keyID {","sourceCodeStart":1915,"sourceCodeEnd":1951,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/kernel/model/attribute_view.go#L1915-L1951","documentation":"Thrown by setAttrViewCardCoverPosition when operation.RowID has no corresponding block value in the AttributeView (attrView.GetBlockValue(RowID) returns nil). The row/item must exist before its card cover position can be set, because the position is keyed off the item ID.","triggerScenarios":"Calling the setAttrViewCardCoverPosition transaction after the row was deleted, before it was committed/flushed, or with a RowID that belongs to a different AttributeView. Also reached if the AV was synced from another device and the row ID was never migrated.","commonSituations":"Stale frontend state that still holds a row reference after a sync/delete; race where a cover-position save fires during row removal; copy-paste of a row ID across notebooks.","solutions":["Refresh the AttributeView rows on the client before allowing cover-position edits, so the RowID is guaranteed to exist.","Verify operation.RowID is present in the current AV block values before enqueueing the transaction (call GetAttributeViewPrimaryKeyValues or equivalent).","If the row was just added, await the transaction commit confirmation before issuing the cover-position operation."],"exampleFix":"// before\ntransaction([{ action: 'setAttrViewCardCoverPosition', avID, rowID: staleRowID, ... }])\n// after\nconst rows = await fetchAvRows(avID)\nif (rows.some(r => r.id === rowID)) {\n  transaction([{ action: 'setAttrViewCardCoverPosition', avID, rowID, ... }])\n}","handlingStrategy":"validation","validationCode":"const rows = await getAttrViewPrimaryKeyValues(avID)\nconst exists = rows.some(r => r.id === operation.rowID)\nif (!exists) { /* row was deleted; do not send cover-position op */ }","typeGuard":null,"tryCatchPattern":"try {\n  await performTx([coverPosOp])\n} catch (e) {\n  if (/attribute view item \\[.*\\] not found/.test(String(e.message ?? e))) {\n    refreshAttrViewRows(avID) // row is gone locally; resync\n  } else { throw e }\n}","preventionTips":["Refresh the AV row list after any delete/sync before allowing cover edits.","Tie cover-position edits to a freshly fetched row handle, not a cached ID."],"tags":["attribute-view","row-not-found","card-cover","transaction"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}