{"record":{"id":"d272acb6b66f84f5","repo":"HumanSignal/label-studio","slug":"is-any-of-is-none-of-support-task-id-inner","errorCode":null,"errorMessage":"`is any of` / `is none of` support Task ID, Inner ID, annotation/prediction counters, and task.data.* fields.","messagePattern":"`is any of` / `is none of` support Task ID, Inner ID, annotation/prediction counters, and task\\.data\\.\\* fields\\.","errorType":"validation","errorClass":"ValidationError","httpStatus":400,"severity":"error","filePath":"label_studio/data_manager/managers.py","lineNumber":582,"sourceCode":"\n\ndef validate_in_list_filter(_filter, field_name: str) -> str:\n    \"\"\"Semantic validation for `in_list` / `not_in_list` operators (BROS-1203).\n\n    Returns one of:\n      - 'ok'   — proceed with the existing Q(__in=value) branch.\n      - 'none' — empty `in_list` after normalization: append a contradiction so the\n                 row contributes no matches (works correctly for both AND and OR).\n      - 'skip' — empty `not_in_list` after normalization: drop the filter entirely.\n\n    Raises ValidationError for unsupported fields. Only triggers when the *original*\n    operator is in_list / not_in_list, so legacy ``annotations_ids`` contains/not_contains\n    filters handled by ``annotation_id_filter_q`` remain unaffected.\n    \"\"\"\n    if _filter.operator not in (Operator.IN_LIST, Operator.NOT_IN_LIST):\n        return 'ok'\n    if not _is_supported_in_list_field(field_name):\n        raise ValidationError(\n            '`is any of` / `is none of` support Task ID, Inner ID, annotation/prediction counters, '\n            'and task.data.* fields.'\n        )\n    if not isinstance(_filter.value, list):\n        raise ValidationError('Filter value must be a list for `is any of` / `is none of`.')\n    _normalize_in_list_value(_filter)\n    if not _filter.value:\n        return 'none' if _filter.operator == Operator.IN_LIST else 'skip'\n    return 'ok'\n\n\ndef add_result_filter(field_name, _filter, filter_expressions, project):\n    from django.db.models.expressions import RawSQL\n    from tasks.models import Annotation, Prediction\n\n    _class = Annotation if field_name == 'annotations_results' else Prediction\n\n    # Annotation","sourceCodeStart":564,"sourceCodeEnd":600,"githubUrl":"https://github.com/HumanSignal/label-studio/blob/0b49e9b53917880baf1dd85d574fe5541a9aafb2/label_studio/data_manager/managers.py#L564-L600","documentation":"validate_in_list_filter restricts the in_list / not_in_list operators to Task ID, Inner ID, annotation/prediction counters, and task.data.* fields (checked via _is_supported_in_list_field). Filtering any other column with these operators raises ValidationError. Legacy annotations_ids contains/not_contains filters are unaffected.","triggerScenarios":"A request filter with operator 'in_list' or 'not_in_list' on an unsupported field such as completed_at, created_by, or an arbitrary non-data column.","commonSituations":"Frontend UI exposing 'is any of' for every column; copied filter payloads from a task.data field applied to a metadata column; older exported views replayed against tightened validation.","solutions":["Switch the operator to one supported by the target field (e.g. contains, equal)","Restrict in_list/not_in_list usage to id, inner_id, annotation/prediction count fields, and data.<key> columns","If list matching on another column is required, reshape the data so the value lives under task.data","Update saved views that embed in_list on unsupported columns"],"exampleFix":"// before\n{\"filter\": \"filter:tasks:created_by\", \"operator\": \"in_list\", \"value\": [1,2]}\n// after\n{\"filter\": \"filter:tasks:data.my_field\", \"operator\": \"in_list\", \"value\": [1,2]}","handlingStrategy":"validation","validationCode":"from data_manager.managers import _is_supported_in_list_field\nfield = f['filter'].removeprefix('filter:tasks:')\nif f['operator'] in ('in_list', 'not_in_list') and not _is_supported_in_list_field(field):\n    raise ValueError(f\"in_list not supported on {field}\")","typeGuard":"def supports_in_list(field): from data_manager.managers import _is_supported_in_list_field; return _is_supported_in_list_field(field)","tryCatchPattern":"try:\n    apply_filters(...)\nexcept ValidationError as e:\n    if 'is any of' in str(e) and 'support' in str(e): switch_operator_to_contains(e)\n    else: raise","preventionTips":["Expose 'is any of' in the UI only for id, inner_id, counters, and data.* fields","Validate saved views against field/operator support after upgrades","Route other columns' list matching through contains or restructure into task.data","Add a mapping table of field -> allowed operators in shared client config"],"tags":["validation","filters","operators","data-manager"],"backgroundTag":"filter-operator-not-allowed","analyzedSha":"0b49e9b53917880baf1dd85d574fe5541a9aafb2","analyzedAt":"2026-08-29T00:39:52.578Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}