{"record":{"id":"9526ca4dbc08303f","repo":"SonarSource/sonarqube","slug":"invalid-format","errorCode":null,"errorMessage":"Invalid format: ","messagePattern":"Invalid format: ","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":400,"severity":"error","filePath":"server/sonar-webserver-webapi/src/main/java/org/sonar/server/common/ParamParsingUtils.java","lineNumber":67,"sourceCode":"  public static Map<ReportKey, Set<String>> parseComplianceStandardsFilter(@Nullable String param) {\n    if (param == null) {\n      return Map.of();\n    }\n\n    String decodedParam;\n    try {\n      decodedParam = URLDecoder.decode(param, StandardCharsets.UTF_8);\n    } catch (IllegalArgumentException e) {\n      throw new IllegalArgumentException(\"Can't URI decode: \" + param, e);\n    }\n\n    Map<ReportKey, Set<String>> categoriesByStandard = new HashMap<>();\n\n    String[] parts = decodedParam.split(\"&\");\n    for (String part : parts) {\n      String[] keyValue = part.split(\"=\");\n      if (keyValue.length != 2) {\n        throw new IllegalArgumentException(\"Invalid format: \" + decodedParam);\n      }\n      Set<String> values = Arrays.stream(keyValue[1].split(\",\")).filter(s -> !s.isBlank()).collect(Collectors.toSet());\n      categoriesByStandard.put(ReportKey.parse(keyValue[0]), values);\n    }\n\n    return categoriesByStandard;\n  }\n}\n","sourceCodeStart":49,"sourceCodeEnd":76,"githubUrl":"https://github.com/SonarSource/sonarqube/blob/184c821202192afc1c599fc912d0889b69fffa53/server/sonar-webserver-webapi/src/main/java/org/sonar/server/common/ParamParsingUtils.java#L49-L76","documentation":"After decoding, parseComplianceStandardsFilter splits the string on '&' and each part on '='; each part must be exactly key=value. If any segment deviates (0 or >1 '='), it throws 'Invalid format: <decodedParam>' as an IllegalArgumentException.","triggerScenarios":"Supplying a filter like 'key' (no =), 'key=a=b' (extra =), or an empty/stray '&' segment in the compliance standards parameter.","commonSituations":"Hand-built query strings not escaped, using ';' instead of '&' as separator, trailing '&' from concatenation, values containing unencoded '='.","solutions":["Format the parameter as repeated key=value segments joined by '&', e.g. cwe=20,89&owaspTop10=a1","Encode '=' inside values as %3D so split(\"=\") still yields exactly two parts","Trim stray '&' separators before sending","Validate with a regex like ^[^=&]+=[^=&]+(&[^=&]+=[^=&]+)*$ client-side"],"exampleFix":"// before\nfilter=cwe=20=89\n// after\nfilter=cwe=20,89","handlingStrategy":"validation","validationCode":"function isValidComplianceFilter(decoded) {\n  return /^([^=&]+=[^=&]+)(&[^=&]+=[^=&]+)*$/.test(decoded);\n}","typeGuard":null,"tryCatchPattern":"try {\n  await api.searchIssues({ complianceStandards: filter });\n} catch (e) {\n  if (e.status === 400 && /Invalid format: /.test(e.message)) {\n    throw new Error(`Filter must be key=value pairs joined by '&': got '${filter}'`);\n  }\n  throw e;\n}","preventionTips":["Build the filter programmatically: pairs.map(([k,v]) => `${k}=${v}`).join('&')","Encode '=' and '&' occurring inside values (%3D, %26)","Trim trailing separators before sending","Validate with the regex above in client code"],"tags":["java","parameter-parsing","query-string"],"backgroundTag":"invalid-argument-format","analyzedSha":"184c821202192afc1c599fc912d0889b69fffa53","analyzedAt":"2026-09-09T12:23:51.573Z","contentChangedAt":"2026-09-09T12:23:51.573Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}