{"record":{"id":"9478d5a6dff82d71","repo":"siyuan-note/siyuan","slug":"rollup-requires-a-supported-operator","errorCode":null,"errorMessage":"rollup requires a supported operator","messagePattern":"rollup requires a supported operator","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/attribute_view_key_config.go","lineNumber":330,"sourceCode":"\t\t}\n\t}\n\treturn err\n}\n\nfunc updateAttributeViewKeyRollup(attrView *av.AttributeView, key *av.Key, op *Operation, value any) error {\n\tif av.KeyTypeRollup != key.Type {\n\t\treturn errors.New(\"rollup requires a rollup field\")\n\t}\n\tvar config struct {\n\t\tRelationKeyID string  `json:\"relationKeyID\"`\n\t\tKeyID         string  `json:\"keyID\"`\n\t\tOperator      *string `json:\"operator\"`\n\t}\n\tif err := decodeAttributeViewKeyConfig(value, &config); nil != err {\n\t\treturn err\n\t}\n\tif nil == config.Operator || !slices.Contains(AttributeViewKeyRollupOperators, *config.Operator) {\n\t\treturn errors.New(\"rollup requires a supported operator\")\n\t}\n\trelationKey, err := attrView.GetKey(config.RelationKeyID)\n\tif nil != err || av.KeyTypeRelation != relationKey.Type || nil == relationKey.Relation {\n\t\treturn errors.New(\"rollup requires a configured relation field\")\n\t}\n\tdest, err := av.ParseAttributeView(relationKey.Relation.AvID)\n\tif nil != err {\n\t\treturn err\n\t}\n\tif _, err = dest.GetKey(config.KeyID); nil != err {\n\t\treturn err\n\t}\n\tcalc := &av.RollupCalc{Operator: av.CalcOperator(*config.Operator)}\n\top.ParentID, op.KeyID = config.RelationKeyID, config.KeyID\n\top.Data = map[string]any{\"calc\": calc}\n\treturn updateAttributeViewColRollup(op)\n}\n","sourceCodeStart":312,"sourceCodeEnd":348,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/model/attribute_view_key_config.go#L312-L348","documentation":"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.","triggerScenarios":"Calling UpdateAttributeViewKeyConfig with rollup config lacking the \"operator\" field, or supplying an unsupported operator string (typo, wrong casing, operator from a different version).","commonSituations":"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.","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"],"exampleFix":"// before\npayload := map[string]any{\"relationKeyID\": relID, \"keyID\": kID, \"operator\": \"Sum All\"} // unsupported\n// after\nif slices.Contains(model.AttributeViewKeyRollupOperators, \"Sum\") {\n    payload := map[string]any{\"relationKeyID\": relID, \"keyID\": kID, \"operator\": \"Sum\"}\n}","handlingStrategy":"validation","validationCode":"const SUPPORTED = ['Count values','Count all','Count non empty','Count empty','Percent non empty','Percent empty','Sum','Average','Median','Min','Max','Latest','Earliest'];\nif (!SUPPORTED.includes(operator)) throw new Error(`unsupported operator: ${operator}`);","typeGuard":null,"tryCatchPattern":"try {\n  await api.updateAttributeViewKeyConfig({avID, keyID, rollup: {relationKeyID, keyID, operator}});\n} catch (e) {\n  if (e.message.includes('supported operator')) {\n    // fall back to a known-good operator like 'Count all'\n  }\n}","preventionTips":["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"],"tags":["attribute-view","rollup","enum"],"backgroundTag":"invalid-enum-value","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}