siyuan-note/siyuan · error
filters must be an array
Error message
filters must be an array
What it means
The settings 'relationFilters' and 'rollupFilters' expect the config value to be an array of filter objects. UpdateAttributeViewKeyConfig type-asserts the value to []any; if the JSON value is an object, string, or null instead of an array, it returns 'filters must be an array'.
Solutions
- Wrap the filter(s) in a JSON array: {"relationFilters": [{...}]} .
- Pass [] (empty array) rather than null to clear filters.
- Validate the payload with Array.isArray(value) (JS) or a schema check before sending.
Example fix
// before
{"relationFilters": {"column": "foo", "value": {}}}
// after
{"relationFilters": [{"column": "foo", "value": {}}]} Defensive patterns
Strategy: type-guard
Validate before calling
// JS: ensure array before sending filters
if (!Array.isArray(filters)) throw new TypeError("filters must be an array"); Type guard
function isFilterArray(v) { return Array.isArray(v) && v.every(f => f && typeof f === "object"); } Try / catch
try { await updateKeyConfig(avID, keyID, { relationFilters: filters }); } catch (e) { if (String(e).includes("filters must be an array")) { throw new TypeError("Wrap filters in an array; use [] to clear"); } throw e; } Prevention
- Always pass arrays; use [] instead of null to clear filters
- Wrap single filters in [filter]
- Validate payloads with Array.isArray before the API call
When it happens
Trigger: Calling UpdateAttributeViewKeyConfig with {"relationFilters": {"value": ...}} (object instead of array), {"rollupFilters": null}, or {"relationFilters": ""}.
Common situations: A client sends a single filter object without wrapping it in an array; a null is passed when no filters are intended (use an empty array [] instead); a payload built by string concatenation loses array structure.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- block [ ] is not an instance of attribute view [ ]
- date display format is only available for date fields
- filter must not be null
- invalid attribute view column widths
- invalid attribute view field template
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/ba4d49bc7d448f48.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/model/attribute_view_key_config.go:118
return fmt.Errorf("%s requires a date field", setting)
}
if "autoFillNow" == setting {
return setAttributeViewColDateFillCreated(op)
}
return setAttrViewColDateFillSpecificTime(op)
case "options", "optionUpdate", "optionRemove":
if av.KeyTypeSelect != key.Type && av.KeyTypeMSelect != key.Type {
return errors.New("option settings require a select or mSelect field")
}
return updateAttributeViewKeyOptions(attrView, key, op, setting, value)
case "relation":
return updateAttributeViewKeyRelation(key, op, value)
case "rollup":
return updateAttributeViewKeyRollup(attrView, key, op, value)
case "relationFilters", "rollupFilters":
filters, ok := value.([]any)
if !ok {
return errors.New("filters must be an array")
}
if err = validateAttributeViewKeyFilters(attrView, key, setting, filters); nil != err {
return err
}
return setAttrViewColFilters(avID, "", keyID, filters, "relationFilters" == setting)
default:
return fmt.Errorf("unknown field setting: %s", setting)
}
}
return
}
func validateAttributeViewKeyFilters(attrView *av.AttributeView, key *av.Key, setting string, value []any) error {
relationKey := key
if "rollupFilters" == setting {
if av.KeyTypeRollup != key.Type || nil == key.Rollup {
return errors.New("rollupFilters requires a configured rollup field")
}View on GitHub (pinned to 9f775e8a12)