siyuan-note/siyuan · error

rollup requires a rollup field

Error message

rollup requires a rollup field

What it means

updateAttributeViewKeyRollup applies rollup (aggregate) configuration to a key. This error is thrown when the target key's type is not av.KeyTypeRollup, i.e. the caller attempted to set rollup configuration on a field that is not a rollup field.

Solutions

  1. Confirm the key type is av.KeyTypeRollup before sending rollup configuration
  2. Create a new rollup field if aggregation is needed on a non-rollup key
  3. Re-fetch the key to verify its type — it may have been modified since you cached it

Example fix

// before
UpdateAttributeViewKeyConfig(avID, viewID, &conf.AttributeViewKeyConfig{KeyID: relKeyID, Rollup: rollupCfg})
// after
if key, _ := attrView.GetKey(relKeyID); key.Type == av.KeyTypeRollup {
    UpdateAttributeViewKeyConfig(avID, viewID, &conf.AttributeViewKeyConfig{KeyID: relKeyID, Rollup: rollupCfg})
}
Defensive patterns

Strategy: type-guard

Validate before calling

const key = av.keys.find(k => k.id === keyID);
const isRollup = key && key.type === 'rollup';

Type guard

function isRollupKey(key) {
  return !!key && key.type === 'rollup';
}

Try / catch

try {
  await api.updateAttributeViewKeyConfig({avID, keyID, rollup: cfg});
} catch (e) {
  if (e.message.includes('rollup requires a rollup field')) {
    // target key is not a rollup; create one instead
  }
}

Prevention

When it happens

Trigger: Calling UpdateAttributeViewKeyConfig with rollup config (relationKeyID, keyID, operator) against a key whose Type != KeyTypeRollup.

Common situations: Reusing a key ID from a changed/deleted field; confusing relation and rollup keys (a rollup references a relation key but is itself a distinct type); copy-pasted config code applying rollup settings to relation keys.

Understand the failure class

Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.

Related errors


AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19). Data as JSON: /api/errors/a2613a1c1cfab490. Report an issue: GitHub.

Appendix: source

Thrown at kernel/model/attribute_view_key_config.go:319

			}
			if "" == config.BackKeyName {
				op.Name = backKey.Name
			}
		}
	}
	err = updateAttributeViewColRelation(op)
	if nil == err {
		ReloadAttrView(config.AvID)
		if nil != key.Relation && key.Relation.AvID != config.AvID {
			ReloadAttrView(key.Relation.AvID)
		}
	}
	return err
}

func updateAttributeViewKeyRollup(attrView *av.AttributeView, key *av.Key, op *Operation, value any) error {
	if av.KeyTypeRollup != key.Type {
		return errors.New("rollup requires a rollup field")
	}
	var config struct {
		RelationKeyID string  `json:"relationKeyID"`
		KeyID         string  `json:"keyID"`
		Operator      *string `json:"operator"`
	}
	if err := decodeAttributeViewKeyConfig(value, &config); nil != err {
		return err
	}
	if nil == config.Operator || !slices.Contains(AttributeViewKeyRollupOperators, *config.Operator) {
		return errors.New("rollup requires a supported operator")
	}
	relationKey, err := attrView.GetKey(config.RelationKeyID)
	if nil != err || av.KeyTypeRelation != relationKey.Type || nil == relationKey.Relation {
		return errors.New("rollup requires a configured relation field")
	}
	dest, err := av.ParseAttributeView(relationKey.Relation.AvID)
	if nil != err {

View on GitHub (pinned to 9f775e8a12)