siyuan-note/siyuan · error
cannot change type of primary key field
Error message
cannot change type of primary key field
What it means
Thrown by updateAttributeViewColumn when changing the type of the primary key (KeyTypeBlock) to any other type. The block key is the structural primary column and must remain type 'block'; its identity cannot be converted to text/number/etc. The inverse direction (changing another column into a block key) produces the sibling error 'cannot change field type to primary key'.
Source
Thrown at kernel/model/attribute_view.go:7171
func updateAttributeViewColumn(operation *Operation) (err error) {
attrView, err := av.ParseAttributeView(operation.AvID)
if err != nil {
return
}
colType := av.KeyType(operation.Typ)
changeType := false
switch colType {
case av.KeyTypeBlock, av.KeyTypeText, av.KeyTypeNumber, av.KeyTypeDate, av.KeyTypeSelect, av.KeyTypeMSelect, av.KeyTypeURL, av.KeyTypeEmail,
av.KeyTypePhone, av.KeyTypeMAsset, av.KeyTypeTemplate, av.KeyTypeCreated, av.KeyTypeUpdated, av.KeyTypeCheckbox,
av.KeyTypeRelation, av.KeyTypeRollup, av.KeyTypeLineNumber:
for _, keyValues := range attrView.KeyValues {
if keyValues.Key.ID == operation.ID {
isPrimaryKey := av.KeyTypeBlock == keyValues.Key.Type
if isPrimaryKey != (av.KeyTypeBlock == colType) {
if isPrimaryKey {
err = errors.New("cannot change type of primary key field")
} else {
err = errors.New("cannot change field type to primary key")
}
return
}
keyValues.Key.Name = strings.TrimSpace(operation.Name)
changeType = keyValues.Key.Type != colType
keyValues.Key.Type = colType
for _, value := range keyValues.Values {
value.Type = colType
}
break
}
}View on GitHub (pinned to 251596fc0d)
Solutions
- Skip the primary (block) key when offering or applying type-change operations on the client.
- Detect KeyTypeBlock on the target column before sending updateAttrViewColumn and disable the type selector for it.
- When scripting bulk retypes, filter out the AV's block key ID explicitly.
Example fix
// before
updateAttributeViewColumn({ avID, id: primaryKeyID, typ: 'text', name })
// after
const target = attrView.GetKey(primaryKeyID)
if (target.Type === 'block') {
throw new Error('primary key type cannot be changed')
}
updateAttributeViewColumn({ avID, id: primaryKeyID, typ: 'text', name }) Defensive patterns
Strategy: validation
Validate before calling
const target = (await getAttrViewKeys(avID)).find(k => k.id === op.id)
if (target && target.type === 'block') { /* disable type-change UI for primary key; skip op */ } Prevention
- Skip the primary (block) key when offering type-change actions.
- Filter block-key IDs out of any bulk retype script.
When it happens
Trigger: A UI or script issues an updateAttrViewColumn operation whose ID targets the primary key but whose Typ is not 'block'. This can happen if the frontend mistakenly offers a type-change affordance on the primary column, or if a replayed operation set references the block key ID.
Common situations: A bulk 'change all columns to X' script that does not skip the primary key; a plugin that lets users retype every column; copy of operations from one AV applied to another where the IDs collide with the primary key.
Related errors
- attribute view [%s] has no block key
- cannot add an attribute view block key
- date display format is only available for date fields
- attribute view [%s] changed while loading search info
- attribute view not found
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/7295d3e4899c528a.
Report an issue: GitHub.