languagetool-org/languagetool · error · UnsupportedOperationException

Too many lemmas (" + value.size() + " for the same hash " +

Error message

Too many lemmas (" + value.size() + " for the same hash " + value + ", the storage needs adjusting

What it means

Capacity guard while grouping entries by hash in the ManualSynthesizer constructor: several distinct lemma+POS pairs collide to the same 32-bit hash and their combined entries no longer fit the fixed-size slot layout, so the compact storage cannot encode them. The input at fault is the loaded data whose lemmas share a hash bucket.

Source

Thrown at languagetool-core/src/main/java/org/languagetool/synthesis/ManualSynthesizer.java:87

    Map<TaggedWord, List<String>> mapping = loadMapping(inputStream);
    Int2ObjectOpenHashMap<List<Triple<String, String, String>>> byHash = groupByHash(mapping);

    map = new Int2IntOpenHashMap(byHash.size());
    int valueCount = mapping.values().stream().mapToInt(v -> v.size()).sum();
    int firstIndex = ENTRY_SIZE; // skip an entry, as 0 means an absent value in TObjectIntHashMap
    data = new String[valueCount * ENTRY_SIZE + firstIndex];
    if (valueCount > MAX_OFFSET) {
      throw new UnsupportedOperationException("Too many values (" + valueCount + "), the storage needs adjusting");
    }
    byHash.int2ObjectEntrySet().fastForEach(new Consumer<Int2ObjectMap.Entry<List<Triple<String, String, String>>>>() {
      int index = firstIndex;

      @Override
      public void accept(Int2ObjectMap.Entry<List<Triple<String, String, String>>> listEntry) {
        int hash = listEntry.getIntKey();
        List<Triple<String, String, String>> value = listEntry.getValue();
        if (value.size() > MAX_LENGTH) {
          throw new UnsupportedOperationException(
            "Too many lemmas (" + value.size() + " for the same hash " + value + ", the storage needs adjusting");
        }
        map.put(hash, ((index / ENTRY_SIZE) << OFFSET_SHIFT) | value.size());
        for (Triple<String, String, String> triple : value) {
          data[index++] = intern(triple.getLeft());
          data[index++] = intern(triple.getMiddle());
          data[index++] = intern(triple.getRight());
        }
      }
    });

    possibleTags = Collections.unmodifiableSet(collectTags(mapping));
  }

  private static Int2ObjectOpenHashMap<List<Triple<String, String, String>>> groupByHash(Map<TaggedWord, List<String>> mapping) {
    Int2ObjectOpenHashMap<List<Triple<String, String, String>>> byHash = new Int2ObjectOpenHashMap<>(mapping.size());
    for (Map.Entry<TaggedWord, List<String>> entry : mapping.entrySet()) {
      TaggedWord tw = entry.getKey();

View on GitHub (pinned to 2e990059ce)

Solutions

  1. Adjust the storage encoding (e.g. allow more entries per hash bucket) so colliding lemmas fit
  2. Rename or restructure the colliding lemma entries in the data file so they hash to different buckets
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at languagetool-core/src/main/java/org/languagetool/synthesis/ManualSynthesizer.java:87 when the library encounters an invalid state.

Common situations: See trigger scenarios.


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