elastic/elasticsearch · error · UnsupportedOperationException

${className} does not support removeAll()

Error message

${className} does not support removeAll()

What it means

LazyPropertyList overrides List.removeAll(Collection) to throw UnsupportedOperationException for the same reason as remove(): bulk removal would force eager evaluation of all deferred suppliers and lose PropertyNormalization metadata. The class is an append/replace-oriented lazy view, not a fully mutable list.

Source

Thrown at build-tools/src/main/java/org/elasticsearch/gradle/LazyPropertyList.java:103

    @Override
    public boolean addAll(Collection<? extends T> c) {
        c.forEach(this::add);
        return true;
    }

    @Override
    public boolean addAll(int index, Collection<? extends T> c) {
        int i = index;
        for (T item : c) {
            this.add(i++, item);
        }
        return true;
    }

    @Override
    public boolean removeAll(Collection<?> c) {
        throw new UnsupportedOperationException(this.getClass().getName() + " does not support removeAll()");
    }

    @Override
    public boolean retainAll(Collection<?> c) {
        throw new UnsupportedOperationException(this.getClass().getName() + " does not support retainAll()");
    }

    @Override
    public void clear() {
        delegate.clear();
    }

    @Override
    public T get(int index) {
        PropertyListEntry<T> entry = delegate.get(index);
        validate(entry);
        return entry.getValue();
    }

View on GitHub (pinned to db6a809a66)

Solutions

  1. Filter into a new list and rebuild: clear() then addAll() the kept entries.
  2. Hoist the removeAll logic to operate on a plain List<T> before populating the LazyPropertyList.
  3. If using Gradle's ListProperty, prefer filtering at the provider level rather than mutating the lazy list.

Example fix

// before
lazyList.removeAll(staleEntries); // UnsupportedOperationException
// after
List<T> kept = lazyList.stream().filter(Predicate.not(staleEntries::contains)).toList();
lazyList.clear();
kept.forEach(lazyList::add);
Defensive patterns

Strategy: validation

Validate before calling

if (list instanceof LazyPropertyList) {
    throw new IllegalStateException("removeAll() not supported on LazyPropertyList");
}

Type guard

static boolean isLazyPropertyList(List<?> l) { return l instanceof LazyPropertyList; }

Try / catch

try { list.removeAll(c); } catch (UnsupportedOperationException e) { /* rebuild: filter and clear+addAll */ }

Prevention

When it happens

Trigger: Calling .removeAll(Collection) on a LazyPropertyList. Encountered when generic collection algorithms (filtering, differencing) operate on the list, or when code attempts to diff two lists and subtract.

Common situations: Refactoring config-building code that did list.removeAll(obsoleteEntries) onto a LazyPropertyList; Gradle plugins that prune entries conditionally; copy-paste from ArrayList-based code.

Related errors


AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12). Data as JSON: /api/errors/6d0d45c8617da3a8. Report an issue: GitHub.