HumanSignal/label-studio · error · ValidationError
Filter value must be a list for `is any of` / `is none of`.
Error message
Filter value must be a list for `is any of` / `is none of`.
What it means
When the operator is in_list/not_in_list, validate_in_list_filter requires _filter.value to be a Python list. Any other type raises ValidationError('Filter value must be a list for `is any of` / `is none of`.').
Source
Thrown at label_studio/data_manager/managers.py:587
Returns one of:
- 'ok' — proceed with the existing Q(__in=value) branch.
- 'none' — empty `in_list` after normalization: append a contradiction so the
row contributes no matches (works correctly for both AND and OR).
- 'skip' — empty `not_in_list` after normalization: drop the filter entirely.
Raises ValidationError for unsupported fields. Only triggers when the *original*
operator is in_list / not_in_list, so legacy ``annotations_ids`` contains/not_contains
filters handled by ``annotation_id_filter_q`` remain unaffected.
"""
if _filter.operator not in (Operator.IN_LIST, Operator.NOT_IN_LIST):
return 'ok'
if not _is_supported_in_list_field(field_name):
raise ValidationError(
'`is any of` / `is none of` support Task ID, Inner ID, annotation/prediction counters, '
'and task.data.* fields.'
)
if not isinstance(_filter.value, list):
raise ValidationError('Filter value must be a list for `is any of` / `is none of`.')
_normalize_in_list_value(_filter)
if not _filter.value:
return 'none' if _filter.operator == Operator.IN_LIST else 'skip'
return 'ok'
def add_result_filter(field_name, _filter, filter_expressions, project):
from django.db.models.expressions import RawSQL
from tasks.models import Annotation, Prediction
_class = Annotation if field_name == 'annotations_results' else Prediction
# Annotation
if field_name == 'annotations_results':
subquery = Q(
id__in=Annotation.objects.annotate(json_str=RawSQL('cast(result as text)', ''))
.filter(Q(project=project) & Q(json_str__contains=_filter.value))
.filter(task=OuterRef('pk'))View on GitHub (pinned to 0b49e9b539)
Solutions
- Send value as a JSON array: value: [1,2,3]
- Parse string inputs with json.loads before submitting
- Client-side check Array.isArray(value) when using in_list/not_in_list
- Normalize comma-separated input into an array in the UI layer
Example fix
// before
{"operator": "in_list", "value": "1,2,3"}
// after
{"operator": "in_list", "value": [1,2,3]} Defensive patterns
Strategy: type-guard
Validate before calling
if f['operator'] in ('in_list', 'not_in_list') and not Array.isArray(f.value):
f.value = typeof f.value === 'string' ? f.value.split(',').map(s => s.trim()) : [f.value]; Type guard
const isListValue = (v) => Array.isArray(v);
Try / catch
try {
await applyFilters(payload);
} catch (e) {
if (/must be a list/.test(e.message)) { payload.filters = wrapValuesInArrays(payload.filters); return applyFilters(payload); }
throw e;
} Prevention
- Coerce scalar inputs to single-element arrays at the form layer
- Parse JSON strings before submitting filter payloads
- Type filter values as unknown[] for list operators in client code
- Add request-level schema validation (zod: z.array(z.unknown()))
When it happens
Trigger: Sending {operator:'in_list', value:'abc'} or value: 5 (scalar/string) instead of an array; a JSON string that was not parsed before validation; a client sending a comma-separated string.
Common situations: Hand-written API calls omitting the brackets; double-encoded JSON (value serialized twice); frontend passing the raw input text of a multi-select.
Related errors
- `is any of` / `is none of` support Task ID, Inner ID, annota
- User filter values must be integer ids.
- Not supported filter type
- Child filters cannot contain nested child filters
- Can't find '{action_id}' in registered actions
AI-assisted analysis of HumanSignal/label-studio@0b49e9b539 (2026-08-29).
Data as JSON: /api/errors/b2563e4dd1abd322.
Report an issue: GitHub.