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

  1. Recreate the database column of type 'block' (primary key) in the view, or rebuild the database from source blocks.
  2. Restore the .av file from backup/history (SiYuan file history) and re-index.
  3. 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

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


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)