{"record":{"id":"62e46498bc5e1604","repo":"siyuan-note/siyuan","slug":"rollup-requires-a-configured-relation-field","errorCode":null,"errorMessage":"rollup requires a configured relation field","messagePattern":"rollup requires a configured relation field","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/attribute_view_key_config.go","lineNumber":334,"sourceCode":"\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":316,"sourceCodeEnd":348,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/model/attribute_view_key_config.go#L316-L348","documentation":"A rollup aggregates values through a relation field in the same attribute view. This error is thrown when the relationKeyID in the rollup config cannot be resolved (GetKey error), resolves to a non-relation key, or the key has no Relation configured — so there is no valid relation field to walk for aggregation.","triggerScenarios":"Calling UpdateAttributeViewKeyConfig with rollup config whose relationKeyID points to a deleted key, a non-relation key, or a relation key that has no target view set (Relation == nil).","commonSituations":"The referenced relation field was deleted or converted to another type after the rollup config was drafted; relationKeyID copied from another view; a relation key created but never assigned a target avID.","solutions":["Point relationKeyID at an existing relation key in the same attribute view that has a configured target (Relation.AvID set)","Recreate the relation field if it was deleted, then retry the rollup update","Validate with attrView.GetKey(relationKeyID) that the key exists, is KeyTypeRelation, and has non-nil Relation before calling"],"exampleFix":"// before\npayload := map[string]any{\"relationKeyID\": deletedRelID, \"keyID\": kID, \"operator\": \"Count\"}\n// after\nif rk, err := attrView.GetKey(relID); err == nil && rk.Type == av.KeyTypeRelation && rk.Relation != nil {\n    payload := map[string]any{\"relationKeyID\": relID, \"keyID\": kID, \"operator\": \"Count\"}\n}","handlingStrategy":"validation","validationCode":"const relKey = av.keys.find(k => k.id === relationKeyID);\nconst ok = relKey && relKey.type === 'relation' && relKey.relation && relKey.relation.avID;\nif (!ok) throw new Error('rollup needs a configured relation field');","typeGuard":"function isConfiguredRelationKey(key) {\n  return !!key && key.type === 'relation' && !!key.relation && !!key.relation.avID;\n}","tryCatchPattern":"try {\n  await api.updateAttributeViewKeyConfig({avID, keyID, rollup: cfg});\n} catch (e) {\n  if (e.message.includes('configured relation field')) {\n    // re-point relationKeyID at a valid relation key\n  }\n}","preventionTips":["Keep the relation field the rollup depends on alive in the same view","Assign a target view to relation keys before using them in rollups","Validate relationKeyID, its type, and its Relation.avID before calling"],"tags":["attribute-view","rollup","relation"],"backgroundTag":"entity-not-found","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"}