stanfordnlp/CoreNLP · error · IllegalArgumentException
Too few columns: / (offset: )
Error message
Too few columns: <columnI>/<numColumns> (offset: <offset>)
What it means
Thrown by the same CSV/TSV line parser when a row ENDS with fewer fields than numColumns: at a newline outside quotes, columnI must equal numColumns-1, otherwise the line has too few columns. The exception reports columnI/numColumns and the offset of the line in the input.
Solutions
- Fix or remove the short/blank lines in the source file (check for a trailing empty line).
- Set numColumns to the true (consistent) column count of the data.
- Pre-filter lines: skip empty lines and validate field count before feeding the parser.
- If trailing fields are legitimately optional, pad short lines with empty strings before parsing.
Example fix
// before
List<String[]> cols = IOUtils.csvStringToColumns(IOUtils.slurpFileNoExceptions(f, "UTF-8"), 4);
// after
String[] rows = Arrays.stream(IOUtils.slurpFileNoExceptions(f, "UTF-8").split("\n"))
.filter(l -> !l.trim().isEmpty()).toArray(String[]::new);
for (String r : rows) {
if (r.split(",").length != 4) throw new IllegalArgumentException("Bad row: " + r);
}
List<String[]> cols = IOUtils.csvStringToColumns(String.join("\n", rows), 4); Defensive patterns
Strategy: validation
Validate before calling
String[] lines = csvText.split("\n", -1);
if (!lines[lines.length - 1].trim().isEmpty()) { /* no trailing newline artifact */ }
for (int i = 0; i < lines.length; i++) {
if (lines[i].trim().isEmpty()) continue; // skip blank lines
if (lines[i].split(",", -1).length != numColumns)
throw new IllegalArgumentException("Line " + (i + 1) + " has wrong field count");
} Try / catch
try {
List<String[]> cols = IOUtils.csvStringToColumns(csvText, numColumns);
} catch (IllegalArgumentException e) {
throw new DataFormatException("Short row in CSV (offset " + e.getMessage() + "): fix or skip line");
} Prevention
- Strip/skip blank and header lines before parsing.
- Confirm numColumns matches the current schema version of the data files.
- Reject ragged files at ingestion rather than mid-parse.
When it happens
Trigger: Calling the CSV reader with a numColumns larger than some row's actual field count: short/truncated lines, trailing blank lines parsed as rows, a header row with fewer fields, or data rows with optional trailing fields omitted.
Common situations: Files exported with ragged rows (optional last column empty and dropped); a blank line at end of file being counted as a malformed row; schema changed from 4 to 5 columns but old data files still in the pipeline; manual edits deleting a trailing comma.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Too many columns: / (offset: )
- Cannot parse Trilean from string: " + value
- Bad data format:
- Bad number put into wordToNumber. Word is: \"" + input +…
- Error in wordToNumber function.
AI-assisted analysis of stanfordnlp/CoreNLP@1b7edd19c4 (2026-09-10).
Data as JSON: /api/errors/57763300723cef40.
Report an issue: GitHub.
Appendix: source
Thrown at src/edu/stanford/nlp/io/IOUtils.java:1463
//(case: field separator)
if(inQuotes){
buffer[columnI].append(',');
} else {
columnI += 1;
if(columnI >= numColumns){
throw new IllegalArgumentException("Too many columns: "+columnI+"/"+numColumns+" (offset: " + offset + ")");
}
buffer[columnI] = new StringBuilder();
}
break;
case '\n':
//(case: newline)
if(inQuotes){
buffer[columnI].append('\n');
} else {
//((error checks))
if(columnI != numColumns-1){
throw new IllegalArgumentException("Too few columns: "+columnI+"/"+numColumns+" (offset: " + offset + ")");
}
//((create line))
String[] rtn = new String[buffer.length];
for(int i=0; i<buffer.length; i++){ rtn[i] = buffer[i].toString(); }
lines.add(rtn);
//((update state))
columnI = 0;
buffer[columnI] = new StringBuilder();
}
break;
case '\\':
nextIsEscaped = true;
break;
default:
buffer[columnI].append(csvContents[offset]);
}
}
}View on GitHub (pinned to 1b7edd19c4)