{"record":{"id":"5b2bbbbe74edd66b","repo":"languagetool-org/languagetool","slug":"listunknownwords-is-set-to-false-unknown-words-no","errorCode":null,"errorMessage":"listUnknownWords is set to false, unknown words not stored","messagePattern":"listUnknownWords is set to false, unknown words not stored","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"languagetool-core/src/main/java/org/languagetool/JLanguageTool.java","lineNumber":1737,"sourceCode":"  protected void rememberUnknownWords(AnalyzedSentence analyzedText) {\n    if (listUnknownWords) {\n      AnalyzedTokenReadings[] atr = analyzedText.getTokensWithoutWhitespace();\n      for (AnalyzedTokenReadings reading : atr) {\n        if (!reading.isTagged()) {\n          unknownWords.add(reading.getToken());\n        }\n      }\n    }\n  }\n\n  /**\n   * Get the alphabetically sorted list of unknown words in the latest run of one of the {@link #check(String)} methods.\n   *\n   * @throws IllegalStateException if {@link #setListUnknownWords(boolean)} has been set to {@code false}\n   */\n  public List<String> getUnknownWords() {\n    if (!listUnknownWords) {\n      throw new IllegalStateException(\"listUnknownWords is set to false, unknown words not stored\");\n    }\n    List<String> words = new ArrayList<>(unknownWords);\n    Collections.sort(words);\n    return words;\n  }\n\n  // non-private only for test case\n  static int countLineBreaks(String s) {\n    int pos = -1;\n    int count = 0;\n    while (true) {\n      int nextPos = s.indexOf('\\n', pos + 1);\n      if (nextPos == -1) {\n        break;\n      }\n      pos = nextPos;\n      count++;\n    }","sourceCodeStart":1719,"sourceCodeEnd":1755,"githubUrl":"https://github.com/languagetool-org/languagetool/blob/2e990059ce67d5e2a0f7f7ca5d31160c6709df4b/languagetool-core/src/main/java/org/languagetool/JLanguageTool.java#L1719-L1755","documentation":"JLanguageTool.getUnknownWords() returns the sorted list of unknown (not-in-dictionary) words collected during the last check() run. Unknown-word collection is opt-in via setListUnknownWords(true); when it is disabled the words are never stored, so calling getUnknownWords() throws IllegalStateException because there is no meaningful data to return.","triggerScenarios":"Calling getUnknownWords() while listUnknownWords is false — the default or after explicitly calling setListUnknownWords(false).","commonSituations":"Developers calling getUnknownWords() on a default-configured JLanguageTool instance, or after reusing an instance whose listUnknownWords flag was reset/disabled, forgetting that collection is off by default.","solutions":["Call tool.setListUnknownWords(true) before running check()","Re-check the text with a fresh JLanguageTool after enabling collection, since only the latest run's words are stored","Only call getUnknownWords() when the flag is known to be enabled"],"exampleFix":"// before\nList<String> unknown = tool.getUnknownWords(); // IllegalStateException\n// after\ntool.setListUnknownWords(true);\ntool.check(\"Your text here\");\nList<String> unknown = tool.getUnknownWords();","handlingStrategy":"validation","validationCode":"if (tool.getListUnknownWords()) { List<String> unknown = tool.getUnknownWords(); }","typeGuard":null,"tryCatchPattern":"try { List<String> unknown = tool.getUnknownWords(); } catch (IllegalStateException e) { /* enable setListUnknownWords(true) and re-run */ }","preventionTips":["Always call setListUnknownWords(true) right after constructing JLanguageTool if you need unknown words","Remember only the latest check() run's words are kept — re-check after enabling the flag","Wrap getUnknownWords() with the same flag check used to enable collection"],"tags":["java","illegal-state","api-misuse"],"backgroundTag":"invalid-state-transition","analyzedSha":"2e990059ce67d5e2a0f7f7ca5d31160c6709df4b","analyzedAt":"2026-09-06T09:20:17.015Z","contentChangedAt":"2026-09-06T09:20:17.015Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}