languagetool-org/languagetool · error · RuntimeException
plainTextPosition must be > 0 - its value starts at 1
Error message
plainTextPosition must be > 0 - its value starts at 1
What it means
PlainTextMapping maps positions in converted plain text back to original Wikipedia text positions. Positions are one-based, so getOriginalTextPositionFor rejects values below 1 with this RuntimeException. It indicates a caller passed a zero-based or invalid position.
Source
Thrown at languagetool-wikipedia/src/main/java/org/languagetool/dev/wikipedia/PlainTextMapping.java:52
public PlainTextMapping(String plainText, Map<Integer, Location> mapping) {
this.plainText = plainText;
this.mapping = mapping;
}
public String getPlainText() {
return plainText;
}
public Map<Integer, Location> getMapping() {
return mapping;
}
/**
* @param plainTextPosition not zero-based - smallest value is 1!
*/
public Location getOriginalTextPositionFor(int plainTextPosition) {
if (plainTextPosition < 1) {
throw new RuntimeException("plainTextPosition must be > 0 - its value starts at 1");
}
Location origPosition = mapping.get(plainTextPosition);
if (origPosition != null) {
//System.out.println("mapping " + plainTextPosition + " to " + origPosition + " [direct]");
return origPosition;
}
int minDiff = Integer.MAX_VALUE;
Location bestMatch = null;
//Integer bestMaybeClosePosition = null;
// algorithm: find the closest lower position
for (Map.Entry<Integer, Location> entry : mapping.entrySet()) {
int maybeClosePosition = entry.getKey();
if (plainTextPosition > maybeClosePosition) {
int diff = plainTextPosition - maybeClosePosition;
if (diff >= 0 && diff < minDiff) {
bestMatch = entry.getValue();
//bestMaybeClosePosition = maybeClosePosition;
minDiff = diff;View on GitHub (pinned to 2e990059ce)
Solutions
- Pass 1-based positions: add 1 to zero-based offsets before calling
- Clamp/validate positions before the call
- Check loop bounds so the position never drops below 1
Example fix
// before Location loc = mapping.getOriginalTextPositionFor(idx); // after Location loc = mapping.getOriginalTextPositionFor(idx + 1); // positions are 1-based
Defensive patterns
Strategy: validation
Validate before calling
if (pos < 1) throw new IllegalArgumentException("plainTextPosition is 1-based, got " + pos); Type guard
boolean isValidPosition(Integer p) { return p != null && p >= 1; } Try / catch
try {
loc = mapping.getOriginalTextPositionFor(pos);
} catch (RuntimeException e) {
loc = mapping.getOriginalTextPositionFor(Math.max(1, pos));
} Prevention
- Treat all PlainTextMapping positions as 1-based
- Convert array indices with +1 before mapping
- Add asserts in loops producing positions
When it happens
Trigger: Calling getOriginalTextPositionFor(0) or with a negative value — typically passing a zero-based offset/char index into this one-based API.
Common situations: Off-by-one errors when tracking text positions in downstream tools; iterating arrays with 0-based indices and feeding them directly to the mapping.
Related errors
- Could not map + plainTextPosition + to original position. Ma
- No start error marker ( + errorMarker.getStartMarker() + ) f
- No end error marker ( + errorMarker.getEndMarker() + ) found
- enableMapping not activated
- URL does not seem to be a valid Wikipedia URL: + url
AI-assisted analysis of languagetool-org/languagetool@2e990059ce (2026-09-06).
Data as JSON: /api/errors/80170e164182ca2d.
Report an issue: GitHub.