languagetool-org/languagetool · error · IllegalArgumentException
factor must be > 0: " + score
Error message
factor must be > 0: " + score
What it means
ScoredConfusionSet's constructor documents that the score/factor threshold must be strictly greater than 0; a score <= 0 would make every alternative 'considered correct' vacuously or nonsensically, so it throws IllegalArgumentException with this message.
Source
Thrown at languagetool-core/src/main/java/org/languagetool/rules/ScoredConfusionSet.java:43
/**
* Words that can easily be confused - for internal use only.
* Even though there can be more words in the confusionWords, usually there
* are two, as the factor is specific for this pair of words.
* A ScoredConfusionSet has a positive score associated with it.
* TODO remove code duplication with ConfusionSet
*/
public class ScoredConfusionSet {
private List<ConfusionString> confusionWords;
private final float score;
/**
* @param score the score that a string must get at least to be considered a correction, must be > 0
*/
public ScoredConfusionSet(float score, List<ConfusionString> words) {
if (score <= 0) {
throw new IllegalArgumentException("factor must be > 0: " + score);
}
this.score = score;
confusionWords = words;
}
/* Alternative must be at least this much more probable to be considered correct. */
public float getScore() {
return score;
}
public List<String> getConfusionTokens() {
return confusionWords.stream().map(ConfusionString::getString).collect(Collectors.toList());
}
public List<Optional<String>> getTokenDescriptions() {
return confusionWords.stream()
.map(ConfusionString::getDescription)
.map(Optional::ofNullable)View on GitHub (pinned to 2e990059ce)
Solutions
- Pass a positive score (e.g. 0.5f) when constructing ScoredConfusionSet.
- Check the source data/config that supplies the score; fix zero or negative entries.
- Add a caller-side guard or default (e.g. Math.max(score, MIN_SCORE)) before constructing.
Example fix
// before
float score = Float.parseFloat(props.getProperty("factor", "0"));
ScoredConfusionSet set = new ScoredConfusionSet(score, words);
// after
float score = Float.parseFloat(props.getProperty("factor", "1.0"));
if (score <= 0) throw new IllegalArgumentException("confusion set factor must be > 0");
ScoredConfusionSet set = new ScoredConfusionSet(score, words); Defensive patterns
Strategy: validation
Validate before calling
if (!(score > 0) || Float.isNaN(score)) {
throw new IllegalArgumentException("ScoredConfusionSet score must be > 0, got: " + score);
} Type guard
boolean isValidScore(float score) { return score > 0.0f && !Float.isNaN(score); } Try / catch
try {
set = new ScoredConfusionSet(score, words);
} catch (IllegalArgumentException e) {
LOG.warn("Falling back to default score: {}", e.getMessage());
set = new ScoredConfusionSet(1.0f, words);
} Prevention
- Never default the score to 0 — use a sane positive default
- Sanity-check parsed floats from data files (NaN/0/empty inputs)
- Document the >0 constraint wherever the score is configured
When it happens
Trigger: Instantiating new ScoredConfusionSet(score, words) with score = 0, negative, or NaN-derived value <= 0, e.g. from a mis-parsed config value or default initialization.
Common situations: Confusion-set rules loaded from data files where the score column was missing/zero, float parsing of empty strings yielding 0, or copy-pasted example code with a placeholder score.
Related errors
- No IssueType found for name '" + name + "'. Valid values: "
- Unknown mode: <mode>
- '${langCode}' is not a language code known to LanguageTool.
- Format error in file ${path}, line: ${line}
- The number of forms and postags has to be the same in disamb
AI-assisted analysis of languagetool-org/languagetool@2e990059ce (2026-09-06).
Data as JSON: /api/errors/c02889a3dd7e8e75.
Report an issue: GitHub.