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

  1. Skip the primary (block-type) key when batch-changing column types
  2. Detect the primary key by checking keyValues.Key.Type == av.KeyTypeBlock and exclude it from type-change operations
  3. Change the target operation.ID to a non-primary key
  4. 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

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


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)