siyuan-note/siyuan · error
block [%s] is not an instance of attribute view [%s]
Error message
block [%s] is not an instance of attribute view [%s]
What it means
Returned by SetDatabaseBlockVisibleViews (attribute_view.go:1272) when the block referenced by blockID is either not a NodeAttributeView node or its AttributeViewID attribute does not equal the supplied avID. The lookup uses getNodeByBlockID; the type/ID mismatch means the block is not the database block that owns this attribute view.
Source
Thrown at kernel/model/attribute_view.go:1272
visible[viewID] = true
}
var normalized []string
for _, view := range attrView.Views {
if visible[view.ID] {
normalized = append(normalized, view.ID)
}
}
if 1 > len(normalized) {
return errors.New("at least one visible view is required")
}
node, tree, err := getNodeByBlockID(nil, blockID)
if nil != err {
return
}
if ast.NodeAttributeView != node.Type || node.AttributeViewID != avID {
return fmt.Errorf("block [%s] is not an instance of attribute view [%s]", blockID, avID)
}
err = setNodeAttrs(node, tree, map[string]string{
av.NodeAttrVisibleViewIDs: strings.Join(normalized, ","),
})
return
}
func (tx *Transaction) doChangeAttrViewLayout(operation *Operation) (ret *TxErr) {
err := ChangeAttrViewLayout(operation.BlockID, operation.AvID, operation.Layout)
if err != nil {
return &TxErr{code: TxErrHandleAttributeView, id: operation.AvID, msg: err.Error()}
}
return
}
func ChangeAttrViewLayout(blockID, avID string, newLayout av.LayoutType) (err error) {
attrView, err := av.ParseAttributeView(avID)View on GitHub (pinned to 251596fc0d)
Solutions
- Send the blockID and avID that actually belong together — read them from the same NodeAttributeView node (node.AttributeViewID paired with the block's ID).
- If the block mirrors multiple databases, target the specific mirror's avID, not the canonical one.
- Validate node.Type == NodeAttributeView and node.AttributeViewID == avID client-side before submitting.
Example fix
// before: avID taken from the wrong source
transaction({ op: "setAttrViewBlockVisibleViews", blockID, avID: lastOpenedAvID, viewIDs })
// after: read the pair from the node itself
const node = getBlockNode(blockID)
transaction({ op: "setAttrViewBlockVisibleViews", blockID, avID: node.attributeViewID, viewIDs }) Defensive patterns
Strategy: validation
Validate before calling
// Pair blockID with the avID stored on that exact block node.
const node = await fetchBlockAttrs(blockID)
if (node.type !== 'NodeAttributeView' || node.attributeViewID !== avID) {
throw new Error('block is not an instance of this attribute view')
} Type guard
function blockOwnsAv(node: BlockAttrs, avID: string): boolean {
return node.type === 'NodeAttributeView' && node.attributeViewID === avID
} Prevention
- Read avID from the same NodeAttributeView node whose ID is blockID.
- For mirrored databases, target each mirror's own avID pairing.
- Do not reuse an avID from a different database block.
When it happens
Trigger: Calling setAttrViewBlockVisibleViews with a blockID that points to a paragraph/list/heading rather than a database block, or with a blockID whose embedded database (AttributeViewID) differs from operation.AvID — e.g. the block mirrors a different avID, or the IDs were swapped.
Common situations: Frontend sends the avID of one database but the blockID of a block embedding another; copy-paste of a database block where the new block got a new avID but the UI still references the old one; plugin mismatch after mirroring.
Related errors
- at least one visible view is required
- view [%s] not found in attribute view [%s]
- invalid card aspect ratio preset [%v]
- invalid card aspect ratio [%v]
- invalid card size preset [%v]
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/f747551e5f3f03a0.
Report an issue: GitHub.