siyuan-note/siyuan · error

attribute view item [%s] not found

Error message

attribute view item [%s] not found

What it means

Before applying a card cover position, the kernel verifies that the row (attribute view item / block value) identified by operation.RowID exists in the parsed attribute view via GetBlockValue. This error means the row ID does not correspond to any existing row in that view.

Source

Thrown at kernel/model/attribute_view.go:2065

		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 8641553a1f)

Solutions

  1. Re-fetch the attribute view and confirm the row ID still exists before sending the operation
  2. Refresh the frontend view state if the row was deleted by another session
  3. Verify AvID and RowID belong to the same attribute view
  4. Drop the pending operation if the card was removed — it cannot succeed on retry

Example fix

// before
applyCoverPosition(avID, staleRowID, ...) // row already deleted
// after
const av = await fetchAttrView(avID);
if (!av.blocks.some(b => b.id === rowID)) return refreshView();
applyCoverPosition(avID, rowID, ...)
Defensive patterns

Strategy: validation

Validate before calling

const rowExists = (av, rowID) => av.blocks.some(b => b.id === rowID);
if (!rowExists(await fetchAttrView(avID), rowID)) return refreshView();

Type guard

const blockValue = attrView?.blocks?.find?.(b => b.id === rowID);

Try / catch

try {
  await transaction(op);
} catch (e) {
  if (String(e).includes("attribute view item")) {
    await reloadAttributeView(avID); // row deleted concurrently
  }
}

Prevention

When it happens

Trigger: Calling doSetAttrViewCardCoverPosition with a RowID that was deleted, belongs to a different attribute view, or was never created; also when the AvID and RowID are mismatched after UI state went stale.

Common situations: Concurrent editing where another client deleted the card; stale kanban/gallery state after undo or sync; passing a block ID from a different document; plugin operating on cached row IDs.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11). Data as JSON: /api/errors/ca76b5907e0434d4. Report an issue: GitHub.