HumanSignal/label-studio · error · ValidationError
List-valued user filters support only these operators: {allo
Error message
List-valued user filters support only these operators: {allowed}. What it means
validate_user_filter_operator guards filters on built-in user fields (USER_FILTER_FIELDS). A list-valued filter value may only be used with operators in USER_FILTER_VALUE_OPERATORS (list-style operators such as contains/not_contains); anything else raises Django ValidationError listing the allowed operators.
Source
Thrown at label_studio/data_manager/managers.py:106
class ResolvedUserFilterIds(list):
"""Marker for IDs expanded by trusted backend code after client-input validation."""
def validate_user_filter_operator(field_name, operator, value):
"""Reject unsupported operators for user-list filters (FIT-2435).
List-valued membership filters only support contains / not_contains.
Empty is allowed only for fields in USER_FILTER_EMPTY_FIELDS.
Legacy scalar equal/not_equal/in_list remain accepted so normalize_persisted_user_filter
can recover historical views.
"""
if field_name not in USER_FILTER_FIELDS:
return
if isinstance(value, list):
if operator not in USER_FILTER_VALUE_OPERATORS:
allowed = ', '.join(sorted(USER_FILTER_VALUE_OPERATORS))
raise ValidationError(f'List-valued user filters support only these operators: {allowed}.')
return
allowed = allowed_user_filter_operators(field_name)
if operator in allowed:
return
if operator in LEGACY_USER_FILTER_OPERATORS:
return
allowed_label = ', '.join(sorted(allowed))
raise ValidationError(
f'User filter "{field_name}" does not support operator "{operator}". Allowed: {allowed_label}.'
)
def normalize_persisted_user_filter(field_name, operator, value):
"""Recover historical user-filter shapes without relaxing validation for new writes."""
if field_name not in USER_FILTER_FIELDS:
return operator, valueView on GitHub (pinned to 0b49e9b539)
Solutions
- Use a list operator (e.g. contains / not_contains) whenever the filter value is a list
- Convert the value to a scalar if an equality operator is intended
- Normalize legacy shapes with normalize_persisted_user_filter before validating
- Check USER_FILTER_VALUE_OPERATORS in managers.py for the exact allowed set
Example fix
// before
{"filter": "filter:tasks:created_by", "operator": "equal", "value": ["u1","u2"]}
// after
{"filter": "filter:tasks:created_by", "operator": "contains", "value": ["u1","u2"]} Defensive patterns
Strategy: validation
Validate before calling
from data_manager.managers import USER_FILTER_FIELDS, USER_FILTER_VALUE_OPERATORS
if f['filter'] in USER_FILTER_FIELDS and isinstance(f['value'], list) and f['operator'] not in USER_FILTER_VALUE_OPERATORS:
raise ValueError(f"list value needs one of {sorted(USER_FILTER_VALUE_OPERATORS)}") Type guard
def is_valid_list_user_filter(f): return isinstance(f.get('value'), list) and f.get('operator') in USER_FILTER_VALUE_OPERATORS Try / catch
try:
apply_filters(...)
except ValidationError as e:
if 'List-valued user filters' in str(e): coerce_value_to_scalar_or_list_operator(e)
else: raise Prevention
- Only offer list operators in the UI when the value widget produces arrays
- Normalize legacy filter payloads through normalize_persisted_user_filter
- Keep operator menus driven by backend allowlists, not hardcoded lists
- Write a schema test asserting operator/value type compatibility
When it happens
Trigger: Applying a user filter whose value is a list (e.g. value: ["a","b"]) with a scalar operator like equal, not_equal, or empty via apply_filters or the DataManager validate() path.
Common situations: A saved/dashboard filter built by an older frontend being replayed with list values; hand-written API filters copying list values onto = operators; tests exercising invalid operator/value combos.
Related errors
- User filter "{field_name}" does not support operator "{opera
- `is any of` / `is none of` support Task ID, Inner ID, annota
- Cannot filter on column "{_filter.filter.removeprefix('filte
- Not supported filter type
- Incorrect value type in key "{key}" = "{value}". It should b
AI-assisted analysis of HumanSignal/label-studio@0b49e9b539 (2026-08-29).
Data as JSON: /api/errors/5717445244af48ac.
Report an issue: GitHub.