{"record":{"id":"0cf8afc5709ef279","repo":"SonarSource/sonarqube","slug":"tags-should-be-set-either-by-using-tags-java-o","errorCode":null,"errorMessage":"Tags should be set either by using 'tags = java' or 'tags IN (finance, platform)'","messagePattern":"Tags should be set either by using 'tags = java' or 'tags IN \\(finance, platform\\)'","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":400,"severity":"error","filePath":"server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ws/ProjectMeasuresQueryFactory.java","lineNumber":115,"sourceCode":"      return;\n    }\n    throw new IllegalArgumentException(\"Languages should be set either by using 'languages = java' or 'languages IN (java, js)'\");\n  }\n\n  private static void processTags(Criterion criterion, ProjectMeasuresQuery query) {\n    checkOperator(criterion);\n    Operator operator = criterion.getOperator();\n    String value = criterion.getValue();\n    List<String> values = criterion.getValues();\n    if (value != null && EQ.equals(operator)) {\n      query.setTags(singleton(value));\n      return;\n    }\n    if (!values.isEmpty() && IN.equals(operator)) {\n      query.setTags(new HashSet<>(values));\n      return;\n    }\n    throw new IllegalArgumentException(\"Tags should be set either by using 'tags = java' or 'tags IN (finance, platform)'\");\n  }\n\n  private static void processQualifier(Criterion criterion, ProjectMeasuresQuery query) {\n    checkOperator(criterion);\n    checkValue(criterion);\n    Operator operator = criterion.getOperator();\n    String value = criterion.getValue();\n    checkArgument(EQ.equals(operator), \"Only equals operator is available for qualifier criteria\");\n    String qualifier = Stream.of(ComponentQualifiers.APP, ComponentQualifiers.PROJECT).filter(q -> q.equalsIgnoreCase(value)).findFirst()\n      .orElseThrow(() -> new IllegalArgumentException(format(\"Unknown qualifier : '%s'\", value)));\n    query.setQualifiers(Sets.newHashSet(qualifier));\n  }\n\n  private static void processQuery(Criterion criterion, ProjectMeasuresQuery query) {\n    checkOperator(criterion);\n    Operator operatorValue = criterion.getOperator();\n    String value = criterion.getValue();\n    checkArgument(value != null, \"Query is invalid\");","sourceCodeStart":97,"sourceCodeEnd":133,"githubUrl":"https://github.com/SonarSource/sonarqube/blob/184c821202192afc1c599fc912d0889b69fffa53/server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ws/ProjectMeasuresQueryFactory.java#L97-L133","documentation":"The tags criterion in the project measures/search WS must use either '=' with one tag or 'IN' with a non-empty tag list. processTags throws this IllegalArgumentException when another operator is used or the value list is empty.","triggerScenarios":"Calling api/measures/search_projects with criteria like 'tags > finance', 'tags != platform', 'tags =' (no value), or 'tags IN ()'.","commonSituations":"Hand-edited saved filters; scripting against the WS with operators copied from numeric criteria (where >, < are valid); empty tag variables interpolated into the criteria string.","solutions":["Use 'tags = finance' for one tag or 'tags IN (finance, platform)' for several.","Ensure at least one tag value is present and non-empty.","Only use comparison operators (=, IN) for tags, not relational ones."],"exampleFix":"// before\nString criteria = \"tags > finance\";\n// after\nString criteria = \"tags IN (finance, platform)\";","handlingStrategy":"validation","validationCode":"Set<String> allowed = Set.of(\"=\", \"IN\");\nif (criterion.getKey().equals(\"tags\") && (!allowed.contains(criterion.getOperator()) || criterion.getValues().isEmpty())) {\n  throw new IllegalArgumentException(\"tags requires '=' or 'IN' with at least one tag\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  response = ws.searchProjects(criteria);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage().contains(\"Tags should be set\")) {\n    criteria = criteria.replaceAll(\"tags\\\\s*[^=I][^N]?.*\", \"tags IN (\" + String.join(\", \", tags) + \")\");\n  } else throw e;\n}","preventionTips":["Only generate 'tags = X' or 'tags IN (X, Y)' forms.","Check the tag list is non-empty before building the criterion.","Do not copy operators from numeric criteria (>, <) onto tags."],"tags":["java","sonarqube","web-api","query-parameters"],"backgroundTag":"invalid-argument-value","analyzedSha":"184c821202192afc1c599fc912d0889b69fffa53","analyzedAt":"2026-09-09T12:23:51.573Z","contentChangedAt":"2026-09-09T12:23:51.573Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}