{"record":{"id":"b7a2fba6734fe47b","repo":"siyuan-note/siyuan","slug":"rollupfilters-requires-a-configured-rollup-field","errorCode":null,"errorMessage":"rollupFilters requires a configured rollup field","messagePattern":"rollupFilters requires a configured rollup field","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/attribute_view_key_config.go","lineNumber":135,"sourceCode":"\t\t\tif !ok {\n\t\t\t\treturn errors.New(\"filters must be an array\")\n\t\t\t}\n\t\t\tif err = validateAttributeViewKeyFilters(attrView, key, setting, filters); nil != err {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\treturn setAttrViewColFilters(avID, \"\", keyID, filters, \"relationFilters\" == setting)\n\t\tdefault:\n\t\t\treturn fmt.Errorf(\"unknown field setting: %s\", setting)\n\t\t}\n\t}\n\treturn\n}\n\nfunc validateAttributeViewKeyFilters(attrView *av.AttributeView, key *av.Key, setting string, value []any) error {\n\trelationKey := key\n\tif \"rollupFilters\" == setting {\n\t\tif av.KeyTypeRollup != key.Type || nil == key.Rollup {\n\t\t\treturn errors.New(\"rollupFilters requires a configured rollup field\")\n\t\t}\n\t\tvar err error\n\t\trelationKey, err = attrView.GetKey(key.Rollup.RelationKeyID)\n\t\tif nil != err {\n\t\t\treturn err\n\t\t}\n\t}\n\tif av.KeyTypeRelation != relationKey.Type || nil == relationKey.Relation {\n\t\treturn errors.New(\"filters require 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\tvar filters []*av.ViewFilter\n\tif err = decodeAttributeViewKeyConfig(value, &filters); nil != err {\n\t\treturn err\n\t}","sourceCodeStart":117,"sourceCodeEnd":153,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/model/attribute_view_key_config.go#L117-L153","documentation":"validateAttributeViewKeyFilters resolves which relation the filters apply to. For 'rollupFilters', the target field must be a rollup field that already has a configured Rollup object (set via the 'rollup' setting), because the rollup's RelationKeyID is needed to locate the underlying relation. A non-rollup field or a rollup with no configuration yet triggers this error.","triggerScenarios":"Calling UpdateAttributeViewKeyConfig with {\"rollupFilters\": [...]} where key.Type != KeyTypeRollup, or the rollup field exists but 'rollup' was never configured (key.Rollup == nil).","commonSituations":"A script sets rollupFilters before configuring the rollup itself (wrong order of calls); a field of another type is mistaken for a rollup; a rollup's configuration was cleared earlier.","solutions":["Call UpdateAttributeViewKeyConfig with the 'rollup' setting first to configure the rollup, then set rollupFilters.","Verify the field is a rollup field and has Rollup.RelationKeyID set before sending rollupFilters.","If filters on the relation itself were intended, use 'relationFilters' on the relation field instead."],"exampleFix":"// before\nUpdateAttributeViewKeyConfig(avID, rollupKeyID, {\"rollupFilters\": [filter]})\n// after\nUpdateAttributeViewKeyConfig(avID, rollupKeyID, {\"rollup\": {\"relationKeyID\": relKeyID, \"calc\": ...}})\nUpdateAttributeViewKeyConfig(avID, rollupKeyID, {\"rollupFilters\": [filter]})","handlingStrategy":"validation","validationCode":"// JS: rollup must be configured before rollupFilters\nif (key.type !== \"rollup\" || !key.rollup || !key.rollup.relationKeyID) throw new Error(\"rollupFilters requires a configured rollup field\");","typeGuard":"function isConfiguredRollup(key) { return !!key && key.type === \"rollup\" && !!key.rollup && !!key.rollup.relationKeyID; }","tryCatchPattern":"try { await updateKeyConfig(avID, keyID, { rollupFilters: filters }); } catch (e) { if (String(e).includes(\"configured rollup field\")) { await updateKeyConfig(avID, keyID, { rollup: rollupCfg }); await updateKeyConfig(avID, keyID, { rollupFilters: filters }); } else { throw e; } }","preventionTips":["Always set 'rollup' before 'rollupFilters' — order matters","Check key.rollup is non-null before sending rollupFilters","Use relationFilters on relation fields instead of rollupFilters when no rollup is intended"],"tags":["attribute-view","rollup","prerequisite-missing"],"backgroundTag":"invalid-state-transition","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"}