languagetool-org/languagetool · error · RuntimeException

Could not map + plainTextPosition + to original position. Ma

Error message

Could not map + plainTextPosition + to original position. Mapping: + mapping

What it means

getOriginalTextPositionFor first tries an exact mapping entry; if none exists it searches the closest known position. If no bestMatch could be found at all (mapping empty or positions wildly outside it), it throws this RuntimeException stating the position could not be mapped.

Source

Thrown at languagetool-wikipedia/src/main/java/org/languagetool/dev/wikipedia/PlainTextMapping.java:75

      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;
        }
      }
    }
    if (bestMatch == null) {
      throw new RuntimeException("Could not map " + plainTextPosition + " to original position. Mapping: " + mapping);
    }
    // we assume that when we have found the closest match there's a one-to-one mapping
    // in this region, thus we can add 'minDiff' to get the exact position:
    //System.out.println("mapping " + plainTextPosition + " to line " + bestMatch.line + ", column " +
    //        bestMatch.column + "+" +  minDiff + ", bestMatch was: " + bestMaybeClosePosition +"=>"+ bestMatch);
    return new Location(bestMatch.file, bestMatch.line, bestMatch.column + minDiff);
  }

}

View on GitHub (pinned to 2e990059ce)

Solutions

  1. Ensure the position comes from the same converted text the mapping was built from
  2. Enable mapping at conversion time (enableMapping) so the map is populated
  3. Validate plainTextPosition <= converted text length before querying
  4. Fall back to nearest documented line/column when exact mapping is unavailable

Example fix

// before
Location loc = converter.getMapping().get(...); // mapping empty
// after
converter.setEnableMapping(true);
String plain = converter.convert(originalText); // build mapping before querying
Defensive patterns

Strategy: validation

Validate before calling

if (!converter.isEnableMapping() || plainTextPosition > converter.getConvertedTextLength()) {
  throw new IllegalArgumentException("position unmappable: " + plainTextPosition);
}

Try / catch

try {
  loc = mapping.getOriginalTextPositionFor(pos);
} catch (RuntimeException e) {
  loc = approximateLocation(pos); // fallback to nearest computed line/col
}

Prevention

When it happens

Trigger: Requesting a plainTextPosition that has no entry in the mapping and no plausible nearby entry — usually a position beyond the converted text length or an empty mapping (built without enableMapping).

Common situations: Mapping positions from a different text version than the one converted; calling getMapping while mapping was never enabled so it is empty; position past end of document after edits.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of languagetool-org/languagetool@2e990059ce (2026-09-06). Data as JSON: /api/errors/5d5fd6eea4cc7ff7. Report an issue: GitHub.