{"record":{"id":"87c99dbb41c94169","repo":"SonarSource/sonarqube","slug":"property-key-doesn-t-contain-a-valid-c","errorCode":null,"errorMessage":"\"Property: '\" + key + \"' doesn't contain a valid CSV value: '\" + value + \"'\"","messagePattern":"\"Property: '\" \\+ key \\+ \"' doesn't contain a valid CSV value: '\" \\+ value \\+ \"'\"","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"sonar-plugin-api-impl/src/main/java/org/sonar/api/config/internal/MultivalueProperty.java","lineNumber":62,"sourceCode":"  }\n\n  public static String[] parseAsCsv(String key, String value, UnaryOperator<String> valueProcessor) {\n    String cleanValue = MultivalueProperty.trimFieldsAndRemoveEmptyFields(value);\n    List<String> result = new ArrayList<>();\n    try (CSVParser csvParser = CSVFormat.RFC4180.builder()\n        .setSkipHeaderRecord(true)\n        .setIgnoreEmptyLines(true)\n        .setIgnoreSurroundingSpaces(true)\n        .build()\n      .parse(new StringReader(cleanValue))) {\n      List<CSVRecord> records = csvParser.getRecords();\n      if (records.isEmpty()) {\n        return ArrayUtils.EMPTY_STRING_ARRAY;\n      }\n      processRecords(result, records, valueProcessor);\n      return result.toArray(new String[result.size()]);\n    } catch (IOException | UncheckedIOException e) {\n      throw new IllegalStateException(\"Property: '\" + key + \"' doesn't contain a valid CSV value: '\" + value + \"'\", e);\n    }\n  }\n\n  /**\n   * In most cases we expect a single record. <br>Having multiple records means the input value was splitted over multiple lines (this is common in Maven).\n   * For example:\n   * <pre>\n   *   &lt;sonar.exclusions&gt;\n   *     src/foo,\n   *     src/bar,\n   *     src/biz\n   *   &lt;sonar.exclusions&gt;\n   * </pre>\n   * In this case records will be merged to form a single list of items. Last item of a record is appended to first item of next record.\n   * <p>\n   * This is a very curious case, but we try to preserve line break in the middle of an item:\n   * <pre>\n   *   &lt;sonar.exclusions&gt;","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/SonarSource/sonarqube/blob/184c821202192afc1c599fc912d0889b69fffa53/sonar-plugin-api-impl/src/main/java/org/sonar/api/config/internal/MultivalueProperty.java#L44-L80","documentation":"MultivalueProperty.parseAsCsv parses a property value as CSV. If the CSV reader hits an IOException or UncheckedIOException while parsing, the library wraps it in this IllegalStateException identifying the property key and offending value. It throws because a malformed multi-line CSV value cannot be converted into the expected string array.","triggerScenarios":"Calling parseAsCsv(key, value) with a value containing unbalanced quotes or otherwise malformed CSV that makes the reader fail mid-parse; multi-line Maven values (multiple records) that trip the record processor.","commonSituations":"Comma-separated settings copied from spreadsheets or YAML with embedded quotes; multi-line values pasted from pom.xml; shell escaping corrupting quotes around values.","solutions":["Quote fields containing special CSV characters (commas, quotes, newlines) correctly","Replace smart quotes / odd whitespace introduced by copy-paste with plain ASCII","Escape or remove unbalanced double quotes inside the value","Test the value with a CSV validator before storing it in settings"],"exampleFix":"// before\nsettings.setProperty(\"sonar.sources\", \"a,b\\\"c\");\n// after\nsettings.setProperty(\"sonar.sources\", \"a,\\\"b\\\"\\\"c\\\"\");","handlingStrategy":"validation","validationCode":"// basic CSV sanity check before parsing\nif (value == null || value.trim().isEmpty()) {\n  return new String[0];\n}\nlong quotes = value.chars().filter(c -> c == '\"').count();\nif (quotes % 2 != 0) {\n  throw new IllegalArgumentException(\"unbalanced quotes in CSV value: \" + value);\n}","typeGuard":null,"tryCatchPattern":"try {\n  return MultivalueProperty.parseAsCsv(key, value);\n} catch (IllegalStateException e) {\n  log.error(\"Bad CSV for property {}: {}\", key, e.getCause());\n  return value.split(\",\", -1); // lenient fallback\n}","preventionTips":["Quote CSV fields containing commas/quotes/newlines","Strip smart quotes and multi-line content from pasted values","Validate values with a CSV parser before storing","Keep values single-line unless multi-record is intended"],"tags":["csv","parsing","configuration"],"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"}