{"record":{"id":"a48d5825d534449f","repo":"HumanSignal/label-studio","slug":"user-filter-field-name-does-not-support-operat","errorCode":null,"errorMessage":"User filter \"{field_name}\" does not support operator \"{operator}\". Allowed: {allowed_label}.","messagePattern":"User filter \"(.+?)\" does not support operator \"(.+?)\"\\. Allowed: (.+?)\\.","errorType":"validation","errorClass":"ValidationError","httpStatus":400,"severity":"error","filePath":"label_studio/data_manager/managers.py","lineNumber":116,"sourceCode":"    can recover historical views.\n    \"\"\"\n    if field_name not in USER_FILTER_FIELDS:\n        return\n\n    if isinstance(value, list):\n        if operator not in USER_FILTER_VALUE_OPERATORS:\n            allowed = ', '.join(sorted(USER_FILTER_VALUE_OPERATORS))\n            raise ValidationError(f'List-valued user filters support only these operators: {allowed}.')\n        return\n\n    allowed = allowed_user_filter_operators(field_name)\n    if operator in allowed:\n        return\n    if operator in LEGACY_USER_FILTER_OPERATORS:\n        return\n\n    allowed_label = ', '.join(sorted(allowed))\n    raise ValidationError(\n        f'User filter \"{field_name}\" does not support operator \"{operator}\". Allowed: {allowed_label}.'\n    )\n\n\ndef normalize_persisted_user_filter(field_name, operator, value):\n    \"\"\"Recover historical user-filter shapes without relaxing validation for new writes.\"\"\"\n    if field_name not in USER_FILTER_FIELDS:\n        return operator, value\n    if operator == Operator.EMPTY:\n        if field_name not in USER_FILTER_EMPTY_FIELDS:\n            # Drop unsupported empty (e.g. skipped_by_annotator) to a no-op contains.\n            return Operator.CONTAINS, []\n        try:\n            empty_value = cast_bool_from_str(value)\n        except ValueError:\n            return Operator.CONTAINS, []\n        if isinstance(empty_value, bool):\n            return operator, empty_value","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/HumanSignal/label-studio/blob/0b49e9b53917880baf1dd85d574fe5541a9aafb2/label_studio/data_manager/managers.py#L98-L134","documentation":"validate_user_filter_operator checks a scalar-valued user filter's operator against the per-field allowlist returned by allowed_user_filter_operators(field_name); legacy operators in LEGACY_USER_FILTER_OPERATORS are still tolerated. If the operator is not allowed for that field, ValidationError is raised naming the field, the operator, and the allowed set.","triggerScenarios":"Sending a filter like {filter: 'filter:tasks:created_by', operator: 'in_list', value: 3} or any operator not in that field's allowlist through apply_filters/validate().","commonSituations":"Client UI offering operators the backend doesn't support for a field; copied filter payloads reused across different field types; version drift after operator allowlists were tightened.","solutions":["Use one of the operators listed in the error message for that field","Consult allowed_user_filter_operators(field) to build the operator menu dynamically","If a legacy operator was intended, keep it as-is — legacy names are still accepted","Update stale saved views/filters that embed now-disallowed operators"],"exampleFix":"// before\n{\"filter\": \"filter:tasks:created_by\", \"operator\": \"in_list\", \"value\": 3}\n// after\n{\"filter\": \"filter:tasks:created_by\", \"operator\": \"equal\", \"value\": 3}","handlingStrategy":"validation","validationCode":"from data_manager.managers import allowed_user_filter_operators, LEGACY_USER_FILTER_OPERATORS\nallowed = sorted(allowed_user_filter_operators(field)) + sorted(LEGACY_USER_FILTER_OPERATORS)\nassert f['operator'] in allowed, f\"{f['operator']} not allowed for {field}\"","typeGuard":"def operator_allowed(field, op): return op in allowed_user_filter_operators(field) or op in LEGACY_USER_FILTER_OPERATORS","tryCatchPattern":"try:\n    apply_filters(...)\nexcept ValidationError as e:\n    if 'does not support operator' in str(e): rebuild_filter_with_allowed_operator(e)\n    else: raise","preventionTips":["Build filter UI operator dropdowns from allowed_user_filter_operators","Validate saved views on load and drop unsupported operators","Add regression tests per field/operator combination","Keep client and backend operator enums in sync via a shared contract"],"tags":["validation","filters","operators","django"],"backgroundTag":"filter-operator-not-allowed","analyzedSha":"0b49e9b53917880baf1dd85d574fe5541a9aafb2","analyzedAt":"2026-08-29T00:39:52.578Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}