{"record":{"id":"40ee3e68fde5b54c","repo":"halo-dev/halo","slug":"unsupported-operator","errorCode":null,"errorMessage":"Unsupported operator: {}","messagePattern":"Unsupported operator: (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"api/src/main/java/run/halo/app/extension/router/selector/FieldSelectorConverter.java","lineNumber":32,"sourceCode":"    public Condition convert(SelectorCriteria criteria) {\n        var key = criteria.key();\n        // compatible with old field selector\n        if (\"name\".equals(key)) {\n            key = \"metadata.name\";\n        }\n        switch (criteria.operator()) {\n            case Equals -> {\n                return Queries.equal(key, getSingleValue(criteria));\n            }\n            case NotEquals -> {\n                return Queries.notEqual(key, getSingleValue(criteria));\n            }\n            // compatible with old field selector\n            case IN -> {\n                Set<String> valueArr = defaultIfNull(criteria.values(), Set.of());\n                return Queries.in(key, valueArr);\n            }\n            default -> throw new IllegalArgumentException(\"Unsupported operator: \" + criteria.operator());\n        }\n    }\n\n    String getSingleValue(SelectorCriteria criteria) {\n        if (CollectionUtils.isEmpty(criteria.values())) {\n            throw new IllegalArgumentException(\"No value present for label key: \" + criteria.key());\n        }\n        return criteria.values().iterator().next();\n    }\n}\n","sourceCodeStart":14,"sourceCodeEnd":43,"githubUrl":"https://github.com/halo-dev/halo/blob/d2f5165f9c8f055ffcb3fa9c3f4032821a7b68c8/api/src/main/java/run/halo/app/extension/router/selector/FieldSelectorConverter.java#L14-L43","documentation":"Thrown by FieldSelectorConverter.convert when the SelectorCriteria operator is not one of Equals, NotEquals, or IN (the only operators the field-selector path handles). The Operator enum also defines Exist and NotExist, which are valid for label selectors but have no field-selector query, so a field selector using bare-key existence (`fieldKey`) or negated existence (`!fieldKey`) hits the default branch and throws.","triggerScenarios":"A `?fieldSelector=name` (Exist) or `?fieldSelector=!status` (NotExist) query reaches FieldSelectorConverter; or a future Operator enum constant is added without a case here.","commonSituations":"A client reuses label-selector syntax (bare key for existence) on a fieldSelector query; an SDK builds a SelectorCriteria with Exist/NotExist against field keys; upgrading Halo adds an operator not yet mapped.","solutions":["For field selectors, use only value operators: key=value, key!=value, or key in (a,b). Move existence checks to labelSelector where Exist/NotExist are supported.","If you construct SelectorCriteria programmatically, restrict the operator to Equals/NotEquals/IN for field selectors.","Upgrade both api and application modules together so a new operator is handled on both converter paths."],"exampleFix":"// before\nGET /apis?fieldSelector=name\n\n// after\nGET /apis?labelSelector=app%3Dhalo   // use label existence, or\nGET /apis?fieldSelector=name=in%20(a,b)","handlingStrategy":"validation","validationCode":"Set<Operator> supported = EnumSet.of(Operator.Equals, Operator.NotEquals, Operator.IN);\nif (!supported.contains(criteria.operator())) {\n    throw new IllegalArgumentException(\n        \"Field selector supports only =, !=, and in; got \" + criteria.operator());\n}","typeGuard":"boolean fieldSupported = switch (criteria.operator()) {\n    case Equals, NotEquals, IN -> true;\n    default -> false;\n};","tryCatchPattern":"try {\n    Condition cond = new FieldSelectorConverter().convert(criteria);\n} catch (IllegalArgumentException e) {\n    // re-educate the caller: field selectors accept only value operators\n}","preventionTips":["Use labelSelector (not fieldSelector) for bare-key existence checks.","Document that fieldSelector supports only =, !=, and in().","Keep api and application versions aligned so new operators get cases."],"tags":["java","selector","field-selector","query","api"],"backgroundTag":null,"analyzedSha":"d2f5165f9c8f055ffcb3fa9c3f4032821a7b68c8","analyzedAt":"2026-08-14T00:18:38.915Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}