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

  1. Send value as a JSON array: value: [1,2,3]
  2. Parse string inputs with json.loads before submitting
  3. Client-side check Array.isArray(value) when using in_list/not_in_list
  4. 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

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


AI-assisted analysis of HumanSignal/label-studio@0b49e9b539 (2026-08-29). Data as JSON: /api/errors/b2563e4dd1abd322. Report an issue: GitHub.