siyuan-note/siyuan · error
rollup requires a supported operator
Error message
rollup requires a supported operator
What it means
A rollup configuration must specify an aggregation operator that is one of the supported values in AttributeViewKeyRollupOperators. This error is thrown when the operator is omitted (nil pointer) or its value is not in the supported list.
Solutions
- Supply a non-null operator string that is a member of AttributeViewKeyRollupOperators (e.g. the aggregate names exposed by the UI)
- Check exact spelling/case of the operator value against the supported list
- Omit rollup config entirely rather than sending a partial payload if no change is intended
Example fix
// before
payload := map[string]any{"relationKeyID": relID, "keyID": kID, "operator": "Sum All"} // unsupported
// after
if slices.Contains(model.AttributeViewKeyRollupOperators, "Sum") {
payload := map[string]any{"relationKeyID": relID, "keyID": kID, "operator": "Sum"}
} Defensive patterns
Strategy: validation
Validate before calling
const SUPPORTED = ['Count values','Count all','Count non empty','Count empty','Percent non empty','Percent empty','Sum','Average','Median','Min','Max','Latest','Earliest'];
if (!SUPPORTED.includes(operator)) throw new Error(`unsupported operator: ${operator}`); Try / catch
try {
await api.updateAttributeViewKeyConfig({avID, keyID, rollup: {relationKeyID, keyID, operator}});
} catch (e) {
if (e.message.includes('supported operator')) {
// fall back to a known-good operator like 'Count all'
}
} Prevention
- Copy operator strings from the UI's aggregate menu, not from memory
- Never omit operator — there is no default
- Re-check the supported operator list when upgrading SiYuan versions
When it happens
Trigger: Calling UpdateAttributeViewKeyConfig with rollup config lacking the "operator" field, or supplying an unsupported operator string (typo, wrong casing, operator from a different version).
Common situations: Hard-coded operator strings that don't match the kernel's enum; API clients written before/after operator renames; assuming a default operator exists when the field is omitted.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- ErrInvalidColumnAlign
- invalid card aspect ratio preset
- invalid card layout [ ]
- invalid card size preset
- invalid new item template field value mode
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/9478d5a6dff82d71.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/model/attribute_view_key_config.go:330
}
}
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 {
return err
}
if _, err = dest.GetKey(config.KeyID); nil != err {
return err
}
calc := &av.RollupCalc{Operator: av.CalcOperator(*config.Operator)}
op.ParentID, op.KeyID = config.RelationKeyID, config.KeyID
op.Data = map[string]any{"calc": calc}
return updateAttributeViewColRollup(op)
}
View on GitHub (pinned to 9f775e8a12)