siyuan-note/siyuan · error
attribute view [ ] has no block key
Error message
attribute view [%s] has no block key
What it means
Row-copy code fetches the attribute view's block key values via GetBlockKeyValues; a well-formed database always has a block (primary) key. A nil result means the definition lacks the block key, so source-row lookup is impossible, and this error is returned. It indicates a structurally invalid attribute view.
Solutions
- Recreate the database column of type 'block' (primary key) in the view, or rebuild the database from source blocks.
- Restore the .av file from backup/history (SiYuan file history) and re-index.
- Inspect data/storage/av/<avID>.av JSON and verify a key with type 'block' exists; repair manually only with a backup.
Defensive patterns
Strategy: validation
Validate before calling
const av = await getAttrView(avID);
if (!av.keys.some(k => k.type === "block")) throw new Error(`attribute view ${avID} lacks a block (primary) key`); Type guard
const hasBlockKey = (av: { keys: { type: string }[] }): boolean => av.keys.some(k => k.type === "block"); Try / catch
try { await duplicateRow(avID, srcRowID); } catch (e) { if (String(e).includes("has no block key")) await restoreOrRebuildAv(avID); else throw e; } Prevention
- Always keep one primary (block) column in every database
- Restore .av files from history after corruption instead of hand-editing
- Validate imported/generated .av JSON against the schema before use
When it happens
Trigger: Duplicating a row in an attribute view whose parsed definition has no block key — e.g. a corrupted or hand-edited .av file, or a definition produced by a buggy/older tool that omitted the primary key.
Common situations: Sync merges dropping the primary key; importing attribute views generated by external scripts; truncated or partially written .av JSON after a crash.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- existing back relation is invalid
- [/api/av/batchSetAttributeViewBlockAttrs] parameter [rowID]…
- at least one visible view is required
- attribute view content is unavailable
- attribute view custom color
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/adfadcc2cac5e583.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/model/attribute_view.go:2193
}
ReloadAttrView(avID)
return
}
// DuplicateAttributeViewRow 创建源行的纯文本副本,复制除主键、Rollup、Created、Updated 外的所有字段值,
// 双向关联同步更新目标属性视图的反向关联列。新行 ID 由调用方(前端)生成并通过 newRowID 传入,
// 副本插入到 previousItemID(通常为最后选中的条目)之后。
func DuplicateAttributeViewRow(tx *Transaction, avID, previousItemID, srcRowID, newRowID string) (err error) {
attrView, err := av.ParseAttributeView(avID)
if err != nil {
logging.LogErrorf("parse attribute view [%s] failed: %s", avID, err)
return
}
blockKeyValues := attrView.GetBlockKeyValues()
if nil == blockKeyValues {
err = fmt.Errorf("attribute view [%s] has no block key", avID)
return
}
srcBlockVal := blockKeyValues.GetValue(srcRowID)
if nil == srcBlockVal {
err = fmt.Errorf("source row [%s] not found in attribute view [%s]", srcRowID, avID)
return
}
if "" == newRowID {
newRowID = ast.NewNodeID()
}
now := util.CurrentTimeMillis()
// 创建副本的主键值,强制为纯文本(非绑定块)
blockContent := ""
if nil != srcBlockVal.Block {View on GitHub (pinned to 9f775e8a12)