{"record":{"id":"39753dd09c64df99","repo":"siyuan-note/siyuan","slug":"filters-require-a-configured-relation-field","errorCode":null,"errorMessage":"filters require a configured relation field","messagePattern":"filters require a configured relation field","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/attribute_view_key_config.go","lineNumber":144,"sourceCode":"\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}\n\tif err = av.ValidateFilterDepth(filters); nil != err {\n\t\treturn err\n\t}\n\tvar validate func([]*av.ViewFilter) error\n\tvalidate = func(items []*av.ViewFilter) error {\n\t\tfor _, filter := range items {\n\t\t\tif nil == filter {\n\t\t\t\treturn errors.New(\"filter must not be null\")\n\t\t\t}","sourceCodeStart":126,"sourceCodeEnd":162,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/model/attribute_view_key_config.go#L126-L162","documentation":"Filters (relation or rollup) ultimately target fields of the destination table reached through a relation. validateAttributeViewKeyFilters requires the resolved relation key to be of type 'relation' with a non-nil Relation object (pointing at a destination attribute view). Otherwise it returns 'filters require a configured relation field'.","triggerScenarios":"Calling with {\"relationFilters\": [...]} on a field whose type is not 'relation' or whose Relation is nil (relation not yet configured); or with {\"rollupFilters\": [...]} where the rollup's referenced key (Rollup.RelationKeyID) is not a configured relation field.","commonSituations":"Setting relationFilters before configuring the relation itself via the 'relation' setting; a rollup pointing at a non-relation key (rollup requires the target table's relation); the relation was removed while filters remained.","solutions":["Configure the relation first: UpdateAttributeViewKeyConfig(avID, keyID, {\"relation\": {...}}), then set relationFilters.","For rollupFilters, ensure the rollup's RelationKeyID references a configured relation field in the same attribute view.","Check key.Type / key.Relation via the attribute view API before sending filters."],"exampleFix":"// before\nUpdateAttributeViewKeyConfig(avID, newKeyID, {\"relationFilters\": [filter]})\n// after\nUpdateAttributeViewKeyConfig(avID, newKeyID, {\"relation\": {\"avID\": destAvID, \"backRelationKeyID\": \"\"}})\nUpdateAttributeViewKeyConfig(avID, newKeyID, {\"relationFilters\": [filter]})","handlingStrategy":"validation","validationCode":"// JS: resolved key must be a configured relation\nif (key.type !== \"relation\" || !key.relation || !key.relation.avID) throw new Error(\"filters require a configured relation field\");","typeGuard":"function isConfiguredRelation(key) { return !!key && key.type === \"relation\" && !!key.relation && !!key.relation.avID; }","tryCatchPattern":"try { await updateKeyConfig(avID, keyID, { relationFilters: filters }); } catch (e) { if (String(e).includes(\"configured relation field\")) { await updateKeyConfig(avID, keyID, { relation: relationCfg }); await updateKeyConfig(avID, keyID, { relationFilters: filters }); } else { throw e; } }","preventionTips":["Set 'relation' before 'relationFilters'","For rollupFilters, confirm the rollup's referenced key is itself a configured relation","Re-check field config after any relation removal"],"tags":["attribute-view","relation","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"}