siyuan-note/siyuan · error
cannot change type of primary key field
Error message
cannot change type of primary key field
What it means
In the attribute view column-type-change path, the kernel forbids changing the type of the primary key field (the block-type key) away from block. The primary key identifies rows as blocks, so re-typing it would break row identity. When the existing key is the primary key and the requested type is not block, this error is returned.
Solutions
- Skip the primary (block-type) key when batch-changing column types
- Detect the primary key by checking keyValues.Key.Type == av.KeyTypeBlock and exclude it from type-change operations
- Change the target operation.ID to a non-primary key
- If the semantic goal is a different column, add a new key of the desired type instead of re-typing the block key
Example fix
// before
for _, key := range attrView.KeyValues { changeType(key.Key.ID, newType) }
// after
for _, key := range attrView.KeyValues {
if key.Key.Type == av.KeyTypeBlock { continue } // never re-type the primary key
changeType(key.Key.ID, newType)
} Defensive patterns
Strategy: validation
Validate before calling
const key = attrView.KeyValues.find(kv => kv.Key.ID === op.ID);
if (key && key.Key.Type === "block" && op.Typ !== "block") throw new Error("primary key type is immutable"); Type guard
const isPrimaryKey = (key) => key.type === "block";
Try / catch
try { await updateColType(op); } catch (e) { if (String(e).includes("cannot change type of primary key field")) { /* skip or create a new key instead */ } else { throw e; } } Prevention
- Treat block-type keys as immutable in type-change code paths
- Filter out the primary key when offering re-typing options in UI
- Add new keys for new types rather than mutating the block key
When it happens
Trigger: Calling the update-column / set-column-type API targeting the block-type key's ID with operation.Typ set to any non-block type such as 'text' or 'number'.
Common situations: Plugin or script iterating all keys trying to normalize types including the block key; user-facing code that lets the primary key be selected for re-typing; bulk migration scripts over .av files.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- cannot change field type to primary key
- attribute view has no primary key field
- cannot remove primary key field
- cannot remove primary key field
- database blocks are not supported by createDocTree templates
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/7295d3e4899c528a.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/model/attribute_view.go:7708
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 9f775e8a12)