SonarSource/sonarqube · error · IllegalStateException
"Property: '" + key + "' doesn't contain a valid CSV value…
Error message
"Property: '" + key + "' doesn't contain a valid CSV value: '" + value + "'"
What it means
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.
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
Example fix
// before
settings.setProperty("sonar.sources", "a,b\"c");
// after
settings.setProperty("sonar.sources", "a,\"b\"\"c\""); Defensive patterns
Strategy: validation
Validate before calling
// basic CSV sanity check before parsing
if (value == null || value.trim().isEmpty()) {
return new String[0];
}
long quotes = value.chars().filter(c -> c == '"').count();
if (quotes % 2 != 0) {
throw new IllegalArgumentException("unbalanced quotes in CSV value: " + value);
} Try / catch
try {
return MultivalueProperty.parseAsCsv(key, value);
} catch (IllegalStateException e) {
log.error("Bad CSV for property {}: {}", key, e.getCause());
return value.split(",", -1); // lenient fallback
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: Comma-separated settings copied from spreadsheets or YAML with embedded quotes; multi-line values pasted from pom.xml; shell escaping corrupting quotes around values.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- Failed to parse duration threshold
- Address in property is not a valid address
- allowAllGroups can only be enabled when Auto-provisioning…
- allowAllGroups cannot be enabled when the GitLab URL is…
- allowedGroups cannot be empty when Auto-provisioning is…
AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09).
Data as JSON: /api/errors/87c99dbb41c94169.
Report an issue: GitHub.
Appendix: source
Thrown at sonar-plugin-api-impl/src/main/java/org/sonar/api/config/internal/MultivalueProperty.java:62
}
public static String[] parseAsCsv(String key, String value, UnaryOperator<String> valueProcessor) {
String cleanValue = MultivalueProperty.trimFieldsAndRemoveEmptyFields(value);
List<String> result = new ArrayList<>();
try (CSVParser csvParser = CSVFormat.RFC4180.builder()
.setSkipHeaderRecord(true)
.setIgnoreEmptyLines(true)
.setIgnoreSurroundingSpaces(true)
.build()
.parse(new StringReader(cleanValue))) {
List<CSVRecord> records = csvParser.getRecords();
if (records.isEmpty()) {
return ArrayUtils.EMPTY_STRING_ARRAY;
}
processRecords(result, records, valueProcessor);
return result.toArray(new String[result.size()]);
} catch (IOException | UncheckedIOException e) {
throw new IllegalStateException("Property: '" + key + "' doesn't contain a valid CSV value: '" + value + "'", e);
}
}
/**
* 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).
* For example:
* <pre>
* <sonar.exclusions>
* src/foo,
* src/bar,
* src/biz
* <sonar.exclusions>
* </pre>
* 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.
* <p>
* This is a very curious case, but we try to preserve line break in the middle of an item:
* <pre>
* <sonar.exclusions>View on GitHub (pinned to 184c821202)