languagetool-org/languagetool · error · RuntimeException
Required key '${key}' not found in properties
Error message
Required key '${key}' not found in properties What it means
DatabaseHandler.getProperty requires that a database configuration key be present in the loaded Properties object; if Properties.getProperty returns null it throws a RuntimeException naming the missing key. It backs the dbUrl, dbUser, and dbPassword lookups, so any missing DB connection property aborts startup.
Source
Thrown at languagetool-wikipedia/src/main/java/org/languagetool/dev/dumpcheck/DatabaseHandler.java:87
conn = DriverManager.getConnection(dbUrl, dbUser, dbPassword);
insertSt = conn.prepareStatement(insertSql);
} catch (SQLException | IOException e) {
throw new RuntimeException(e);
}
contextTools = new ContextTools();
contextTools.setContextSize(MAX_CONTEXT_LENGTH);
contextTools.setErrorMarker(MARKER_START, MARKER_END);
contextTools.setEscapeHtml(false);
smallContextTools = new ContextTools();
smallContextTools.setContextSize(SMALL_CONTEXT_LENGTH);
smallContextTools.setErrorMarker(MARKER_START, MARKER_END);
smallContextTools.setEscapeHtml(false);
}
private String getProperty(Properties prop, String key) {
String value = prop.getProperty(key);
if (value == null) {
throw new RuntimeException("Required key '" + key + "' not found in properties");
}
return value;
}
@Override
protected void handleResult(Sentence sentence, List<RuleMatch> ruleMatches, Language language) {
try {
java.sql.Date nowDate = new java.sql.Date(new Date().getTime());
for (RuleMatch match : ruleMatches) {
String smallContext = smallContextTools.getContext(match.getFromPos(), match.getToPos(), sentence.getText());
insertSt.setString(1, language.getShortCode());
Rule rule = match.getRule();
insertSt.setString(2, rule.getId());
insertSt.setString(3, rule.getCategory().getName());
if (rule instanceof AbstractPatternRule) {
AbstractPatternRule patternRule = (AbstractPatternRule) rule;
insertSt.setString(4, patternRule.getSubId());
} else {View on GitHub (pinned to 2e990059ce)
Solutions
- Open the properties file and add the exact key named in the message (e.g. dbUrl=jdbc:mysql://...)
- Check key spelling against what DatabaseHandler expects
- Confirm the -d option points to the intended properties file and that it loaded non-empty content
Example fix
// before (db.properties) databaseUrl=jdbc:mysql://localhost/wiki // after dbUrl=jdbc:mysql://localhost/wiki dbUser=ltuser dbPassword=secret
Defensive patterns
Strategy: validation
Validate before calling
Properties p = new Properties();
try (FileInputStream in = new FileInputStream(propFile)) { p.load(in); }
for (String key : new String[]{"dbUrl", "dbUser", "dbPassword"}) {
if (p.getProperty(key) == null) throw new IllegalStateException("Missing required key: " + key);
} Type guard
static String requireProp(Properties p, String key) {
String v = p.getProperty(key);
if (v == null || v.trim().isEmpty()) throw new IllegalStateException("Missing/empty key: " + key);
return v;
} Try / catch
try {
handler = new DatabaseHandler(props);
} catch (RuntimeException e) {
if (e.getMessage() != null && e.getMessage().contains("not found in properties")) {
System.err.println("Fix your properties file: " + e.getMessage()); System.exit(2);
} else throw e;
} Prevention
- Ship a template properties file with all required keys
- Validate all keys at startup before connecting
- Use a versioned config example in the repo
- Assert file loaded non-empty
When it happens
Trigger: The -d properties file passed to the checker lacks dbUrl, dbUser, or dbPassword, the key is misspelled, or the file is empty/loaded from the wrong path.
Common situations: Copying an old config template missing new keys; typos like 'databaseUrl' vs 'dbUrl'; loading a default/empty properties file because the -d option pointed elsewhere.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- No rules are active. Please make sure your rule ids (<option
- List of language models is empty
- suppressMisspelledMatch must be a valid regex
- suppressMisspelledSuggestions must be a valid regex
- ApostropheTypeFilter: Index out of bounds in
AI-assisted analysis of languagetool-org/languagetool@2e990059ce (2026-09-06).
Data as JSON: /api/errors/22d3c5d9e53422ab.
Report an issue: GitHub.