siyuan-note/siyuan · error
attribute view item [%s] not found
Error message
attribute view item [%s] not found
What it means
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.
Source
Thrown at kernel/model/attribute_view.go:1933
return fmt.Errorf("invalid card cover source [%s]", data.Source)
}
if nil != data.Position {
if "" == data.Position.Image || 32*1024 < len(data.Position.Image) {
return errors.New("invalid card cover image")
}
if math.IsNaN(data.Position.X) || math.IsInf(data.Position.X, 0) ||
math.IsNaN(data.Position.Y) || math.IsInf(data.Position.Y, 0) ||
data.Position.X < 0 || 100 < data.Position.X || data.Position.Y < 0 || 100 < data.Position.Y {
return fmt.Errorf("invalid card cover position [%v, %v]", data.Position.X, data.Position.Y)
}
}
attrView, err := av.ParseAttributeView(operation.AvID)
if nil != err {
return
}
if nil == attrView.GetBlockValue(operation.RowID) {
return fmt.Errorf("attribute view item [%s] not found", operation.RowID)
}
view, err := getAttrViewViewByBlockID(attrView, operation.BlockID)
if nil != err {
return
}
if av.LayoutTypeGallery != view.LayoutType && av.LayoutTypeKanban != view.LayoutType {
return av.ErrWrongLayoutType
}
var source string
if av.LayoutTypeGallery == view.LayoutType {
source = av.CardCoverSource(view.Gallery.CoverFrom, view.Gallery.CoverFromAssetKeyID)
} else {
source = av.CardCoverSource(view.Kanban.CoverFrom, view.Kanban.CoverFromAssetKeyID)
}
if data.Source != source {
return fmt.Errorf("card cover source [%s] does not match view [%s]", data.Source, view.ID)
}
if keyID := av.CardCoverSourceAssetKeyID(data.Source); "" != keyID {View on GitHub (pinned to 251596fc0d)
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.
Example fix
// before
transaction([{ action: 'setAttrViewCardCoverPosition', avID, rowID: staleRowID, ... }])
// after
const rows = await fetchAvRows(avID)
if (rows.some(r => r.id === rowID)) {
transaction([{ action: 'setAttrViewCardCoverPosition', avID, rowID, ... }])
} Defensive patterns
Strategy: validation
Validate before calling
const rows = await getAttrViewPrimaryKeyValues(avID)
const exists = rows.some(r => r.id === operation.rowID)
if (!exists) { /* row was deleted; do not send cover-position op */ } Try / catch
try {
await performTx([coverPosOp])
} catch (e) {
if (/attribute view item \[.*\] not found/.test(String(e.message ?? e))) {
refreshAttrViewRows(avID) // row is gone locally; resync
} else { throw e }
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- invalid card cover position [%v, %v]
- card cover source [%s] does not match view [%s]
- card cover asset field [%s] not found
- source row [%s] not found in attribute view [%s]
- invalid card aspect ratio preset [%v]
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/ca76b5907e0434d4.
Report an issue: GitHub.