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
- Confirm the key type is av.KeyTypeRollup before sending rollup configuration
- Create a new rollup field if aggregation is needed on a non-rollup key
- 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
- Only send rollup config for keys of type rollup
- Verify key type right before the update call
- Distinguish relation keys from rollup keys in your data model
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
- block [ ] is not an instance of attribute view [ ]
- date display format is only available for date fields
- filters must be an array
- invalid attribute view column widths
- invalid attribute view field template
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)