siyuan-note/siyuan · error

attribute view [%s] has no block key

Error message

attribute view [%s] has no block key

What it means

Thrown by DuplicateAttributeViewRow when attrView.GetBlockKeyValues() returns nil, meaning the AttributeView has no primary key (KeyTypeBlock). Every AV must have exactly one block key serving as the primary column; without it, rows cannot be duplicated because the primary value cannot be cloned.

Source

Thrown at kernel/model/attribute_view.go:2046

	}

	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 251596fc0d)

Solutions

  1. Repair the AV by ensuring it has a block-type primary key before allowing row duplication (re-create the key via the kernel's AV repair/normalization path).
  2. Do not expose 'duplicate row' UI affordances if the AV lacks a primary key; guard at the call site.
  3. Restore the AV from a known-good snapshot if the missing primary key indicates wider corruption.

Example fix

// before
DuplicateAttributeViewRow(tx, avID, prevID, srcRowID, newRowID) // AV has no block key
// after
if blockKV := attrView.GetBlockKeyValues(); blockKV == nil {
  return errors.New("cannot duplicate: attribute view is missing its primary block key; repair the AV first")
}
DuplicateAttributeViewRow(tx, avID, prevID, srcRowID, newRowID)
Defensive patterns

Strategy: validation

Validate before calling

const av = await parseAttributeView(avID)
const hasBlockKey = av.keyValues.some(kv => kv.key.type === 'block')
if (!hasBlockKey) { /* offer to repair/restore AV; do not call DuplicateAttributeViewRow */ }

Prevention

When it happens

Trigger: The AV was created/imported without a block key, or the block key was somehow removed (corruption). DuplicateAttributeViewRow relies on the block key to clone the primary cell content into a new row.

Common situations: Hand-crafted or third-party .sy files that skip the primary key; a partial restore that dropped the block key; an AV that was migrated from an older format and never normalized.

Related errors


AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12). Data as JSON: /api/errors/adfadcc2cac5e583. Report an issue: GitHub.