languagetool-org/languagetool · error · RuntimeException
IOException during dictionary list loading
Error message
IOException during dictionary list loading
What it means
ExtraDictionaryLoader.loadLists() reads dictionary lists from an InputStream and wraps any IOException in an unchecked RuntimeException. This is a fail-fast pattern: the dictionary data is required for the rule to work, so the library aborts instead of silently returning partial data. The exception message is generic because the original IOException is used only as the cause.
Source
Thrown at languagetool-language-modules/uk/src/main/java/org/languagetool/rules/uk/ExtraDictionaryLoader.java:68
}
return result;
}
public static Map<String, List<String>> loadLists(String path) {
Map<String, List<String>> result = new HashMap<>();
try (InputStream is = JLanguageTool.getDataBroker().getFromRulesDirAsStream(path);
Scanner scanner = new Scanner(is, "UTF-8")) {
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
if( ! line.startsWith("#") && ! line.trim().isEmpty() ) {
String[] split = line.split(" *= *|\\|");
List<String> list = Arrays.asList(split).subList(1, split.length);
result.put(split[0], list);
}
}
return result;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
View on GitHub (pinned to 2e990059ce)
Solutions
- Check network connectivity and make the source URL reachable (curl it from the same host).
- Verify any proxy settings (-Dhttps.proxyHost/-Dhttps.proxyPort) and truststore configuration for HTTPS sources.
- Inspect the cause chain (e.getCause()) to see the underlying IOException and address it specifically.
- Cache the dictionary list locally and load from a local file/stream instead of the network.
- If the list is no longer hosted, update the URL in the source to the new location.
Example fix
// before
try {
return loadLists(stream);
} catch (IOException e) {
throw new RuntimeException(e);
}
// after
try {
return loadLists(stream);
} catch (IOException e) {
throw new RuntimeException("Failed to load extra dictionary lists from " + sourceUrl, e);
} Defensive patterns
Strategy: try-catch
Validate before calling
URL url = new URL(sourceUrl);
HttpURLConnection c = (HttpURLConnection) url.openConnection();
c.setConnectTimeout(5000);
if (c.getResponseCode() != 200) throw new IllegalStateException("List source unreachable: " + c.getResponseCode()); Try / catch
try { result = loader.loadLists(stream); }
catch (RuntimeException e) {
Throwable cause = e.getCause();
if (cause instanceof IOException) { LOG.error("Dictionary list I/O failure", cause); /* fallback to cached list */ }
else throw e;
} Prevention
- Preflight the remote list URL (HTTP status check) before loading
- Cache dictionary lists locally and fall back to the cache on I/O failure
- Configure proxy/TLS settings for environments behind firewalls
- Monitor cause-chain IOExceptions to detect recurring network problems
When it happens
Trigger: Calling loadLists() when the underlying data source (URL or stream) is unreachable, returns an error, or the connection drops mid-read while splitting lines into key/value lists.
Common situations: No network access or offline environment when loading remote dictionaries; the remote Wikipedia-derived list host is down or rate-limiting; a proxy/firewall blocks the request; TLS failures in restricted JVMs.
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
Related errors
- Could not get rules of language <language>
- Could not load remote rules.
- Could not load remote rules configuration at <configFile.get
- Could not load coherency data from " + path
- Cannot load or parse input stream of '${filename}'
AI-assisted analysis of languagetool-org/languagetool@2e990059ce (2026-09-06).
Data as JSON: /api/errors/734b31dace8c8519.
Report an issue: GitHub.