languagetool-org/languagetool · error · Exception

Error: Lines from the input file should contain at least two

Error message

Error: Lines from the input file should contain at least two tab-separated columns. Line: ${line}

What it means

SentenceAnnotator.runAutomaticAnnotation reads an input file where each line must contain at least two tab-separated columns (sentence and corrected sentence). If splitting a line on tabs yields fewer than two parts, it throws this Exception naming the offending line. The message parameter is actually a hard-coded concatenation, so the dynamic line content is appended after the literal text.

Source

Thrown at languagetool-http-client/src/main/java/org/languagetool/remote/SentenceAnnotator.java:305

  /*
   * If the input file has two tab-separated columns (original sentence, golden sentence),
   * the sentence to be evaluated is generated by the API defined in the configuration.
   *
   * Otherwise, the input file has three tab-separated columns:
   * original sentence, golden sentence, sentence to be evaluated (no API is used)
   */
  private static void runAutomaticAnnotation(AnnotatorConfig cfg) throws Exception {
    DiffsAsMatches diffsAsMatches = new DiffsAsMatches();
    List<String> lines = Files.readAllLines(Paths.get(cfg.inputFilePath));
    int numSentence = 0;
    System.out.println("Starting at line 1 of file " + cfg.inputFilePath);
    for (String line : lines) {
      numSentence++;
      line = line.replace("\u00A0" , " ");
      String[] parts = line.split("\t");
      if (parts.length < 2) {
        throw new Exception("Error: Lines from the input file should contain at least two tab-separated columns. "
          + "Line: " + line);
      }
      String sentence = parts[0].replace("__", "");
      String sentenceHash = md5FromSentence(sentence);
      String correctedSentence = parts[1].replace("__", "");
      List<PseudoMatch> matchesGolden = diffsAsMatches.getPseudoMatches(sentence, correctedSentence);
      if (parts.length < 3) {
        List<RemoteRuleMatch> matches = getMatches(cfg, sentence);
        correctedSentence = applyAllMatches(sentence, matches);
      } else {
        correctedSentence = parts[2].replace("__", "");
      }
      RemoteRuleMatch match = null;
      List<PseudoMatch> matchesEval = diffsAsMatches.getPseudoMatches(sentence, correctedSentence);
      String errorType = "";
      int iGolden = 0;
      int iEval = 0;
      while (iGolden < matchesGolden.size() || iEval < matchesEval.size()) {

View on GitHub (pinned to 2e990059ce)

Solutions

  1. Open the file and fix the reported line so it has sentence<TAB>correction
  2. Skip or sanitize blank/malformed lines before processing (filter lines containing '\t')
  3. Re-export the source data with tab delimiters, not commas or semicolons
  4. Replace literal tab-equivalent markers (e.g. '__' placeholders handled by the tool) consistently in both columns

Example fix

// before: line "This is a sentence" (no tab)
// after
// This is a sentence	This is a corrected sentence
lines.stream().filter(l -> l.contains("\t")).forEach(/* annotate */);
Defensive patterns

Strategy: validation

Validate before calling

List<String> bad = Files.readAllLines(Path.of(cfg.inputFilePath)).stream()
  .filter(l -> l.split("\t", -1).length < 2)
  .collect(Collectors.toList());
if (!bad.isEmpty()) throw new IllegalStateException("lines missing 2nd column: " + bad);

Type guard

static boolean isValidTsvLine(String line) {
  return line != null && line.split("\t", -1).length >= 2;
}

Try / catch

try {
  annotator.run();
} catch (Exception e) {
  if (e.getMessage().contains("at least two tab-separated columns")) {
    System.err.println("fix TSV: " + e.getMessage());
  } else throw e;
}

Prevention

When it happens

Trigger: Feeding a TSV where some lines have only one column — blank lines, lines with spaces instead of tabs, header lines, or files exported with a different delimiter (CSV with commas).

Common situations: Hand-built annotation files with missing second column; spreadsheet export using semicolons/commas; trailing garbage or empty lines at EOF; copy-paste converting tabs to spaces.

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


AI-assisted analysis of languagetool-org/languagetool@2e990059ce (2026-09-06). Data as JSON: /api/errors/f9fd0d815c1c99a0. Report an issue: GitHub.