siyuan-note/siyuan · error
block [ ] is not an instance of attribute view [ ]
Error message
block [%s] is not an instance of attribute view [%s]
What it means
The node identified by blockID must be an ast.NodeAttributeView block whose AttributeViewID equals the given avID. If the block is a different node type, or belongs to a different attribute view, the kernel refuses to write the visible-view IDs attribute onto it.
Solutions
- Verify the block is a database block (type 'NodeAttributeView' in the .sy tree) and read its own avID from node.AttributeViewID / the block's 'av' attribute before calling.
- Use the avID that belongs to the given blockID, not an unrelated attribute view.
- Re-resolve the block by ID after edits; if the block no longer exists as a database, surface a user-facing error instead of retrying.
Example fix
// before
setVisibleViews(someBlockId, avIdFromMemory, viewIds);
// after
const node = getNode(blockId);
if (node && node.type === 'NodeAttributeView') {
setVisibleViews(blockId, node.avId, viewIds);
} Defensive patterns
Strategy: type-guard
Validate before calling
const node = getNode(blockID);
if (!node || node.type !== 'NodeAttributeView' || node.avId !== avID) throw new Error('block is not an instance of this attribute view'); Type guard
const isAttrViewNode = (n: { type: string; avId?: string } | null, avID: string): boolean => !!n && n.type === 'NodeAttributeView' && n.avId === avID; Try / catch
try { await setVisibleViews(blockID, avID, viewIDs); } catch (e) { if (String(e).includes('is not an instance of attribute view')) { console.warn('block/av mismatch', blockID, avID); } else throw e; } Prevention
- Read the avID from the database block itself (node.AttributeViewID) instead of passing it independently
- Re-resolve block IDs after undo/redo or block-type conversion
- Never reuse an avID across copied blocks without re-reading it
When it happens
Trigger: Calling SetDatabaseBlockVisibleViews with a blockID pointing to a paragraph/heading/other block, or to a database block whose attribute view ID differs from the avID argument.
Common situations: Passing a container/parent block ID instead of the database block ID; block was converted to another type; avID copied from another database after copy-pasting blocks; stale references after undo/redo.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- date display format is only available for date fields
- filters must be an array
- invalid attribute view column widths
- invalid attribute view field template
- invalid attribute view source
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/f747551e5f3f03a0.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/model/attribute_view.go:1418
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 9f775e8a12)