languagetool-org/languagetool · error · RuntimeException

IOException while writing debug log line

Error message

IOException while writing debug log line

What it means

CompoundDebugLogger.logLine writes a word to an optional debug file writer for Ukrainian compound-word analysis. If the underlying BufferedWriter throws an IOException (disk full, closed stream, permissions), it is wrapped in a RuntimeException with this message. This is a debug-only aid, so failures abort the tagging pipeline rather than being logged.

Source

Thrown at languagetool-language-modules/uk/src/main/java/org/languagetool/tagging/uk/CompoundDebugLogger.java:71

      return;

    debug_tagged_write(guessedCompoundTags, compoundTaggedDebugWriter);

    guessedCompoundTags.stream().map(t -> t.getLemma()).collect(Collectors.toSet()).forEach( w ->
        logLine(compoundTaggedLemmaDebugWriter, w)
    );
  }

  private static int cnt = 0;
  public void logLine(BufferedWriter writer, String word) {
    if( writer == null )
      return;
    
    try {
      writer.append(word).append('\n');
      if( ++cnt % 10 == 0) writer.flush();
    } catch (IOException e) {
      throw new RuntimeException(e);
    }
  }

  void logUnknownCompound(String word) {
    logLine(compoundUnknownDebugWriter, word);
  }
  
  private void debug_tagged_write(List<AnalyzedToken> analyzedTokens, BufferedWriter writer) {
    if( analyzedTokens.isEmpty()
        || analyzedTokens.get(0).getLemma() == null 
        || analyzedTokens.get(0).getToken().trim().isEmpty() )
      return;

    try {
      String prevToken = "";
      String prevLemma = "";
      for (AnalyzedToken analyzedToken : analyzedTokens) {
        String token = analyzedToken.getToken();

View on GitHub (pinned to 2e990059ce)

Solutions

  1. Check that the debug output directory exists and is writable before enabling compound debug logging
  2. Ensure the writer is not closed before all log calls finish
  3. Inspect the wrapped IOException cause for the real filesystem error
  4. Disable compound debug logging if you do not need it

Example fix

// before
} catch (IOException e) {
  throw new RuntimeException(e);
}
// after
} catch (IOException e) {
  LOGGER.warn("Failed to write compound debug log line", e);
}
Defensive patterns

Strategy: try-catch

Validate before calling

File dbg = new File(debugPath);
if (!dbg.getParentFile().canWrite() || !dbg.getParentFile().exists()) {
    throw new IllegalStateException("Debug dir missing/unwritable: " + debugPath);
}

Try / catch

try {
    logger.logUnknownCompound(word);
} catch (RuntimeException e) {
    if (e.getCause() instanceof IOException) {
        LOGGER.warn("compound debug logging disabled", e.getCause());
    } else throw e;
}

Prevention

When it happens

Trigger: Calling logTaggedCompound or logUnknownCompound while the debug writer's target file is unwritable (missing directory, no permissions, disk full) or already closed.

Common situations: Running LanguageTool Ukrainian tests with compound debug logging enabled on a read-only filesystem or a temp directory that was cleaned up mid-run.

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


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