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

  1. Supply a non-null operator string that is a member of AttributeViewKeyRollupOperators (e.g. the aggregate names exposed by the UI)
  2. Check exact spelling/case of the operator value against the supported list
  3. 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

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


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)