microg/GmsCore · error · UnsupportedOperationException

Cannot remove elements from a DataBufferIterator

Error message

Cannot remove elements from a DataBufferIterator

What it means

DataBufferIterator.remove() unconditionally throws UnsupportedOperationException('Cannot remove elements from a DataBufferIterator'). DataBuffers are read-only views over query results, so the optional Iterator.remove operation is not supported.

Source

Thrown at play-services-base/src/main/java/com/google/android/gms/common/data/DataBufferIterator.java:33

public class DataBufferIterator<T> implements Iterator<T> {
    protected DataBuffer<T> dataBuffer;
    protected int position = -1;

    public DataBufferIterator(@NonNull DataBuffer<T> dataBuffer) {
        this.dataBuffer = dataBuffer;
    }

    @Override
    public T next() {
        if (!hasNext()) {
            throw new NoSuchElementException("Cannot advance the iterator beyond " + position);
        }
        return dataBuffer.get(++position);
    }

    @Override
    public void remove() {
        throw new UnsupportedOperationException("Cannot remove elements from a DataBufferIterator");
    }

    @Override
    public boolean hasNext() {
        return this.position < this.dataBuffer.getCount() - 1;
    }
}

View on GitHub (pinned to 157c9d86ac)

Solutions

  1. Do not call remove(); delete the underlying data (e.g. via the content resolver/API that produced the DataBuffer) instead.
  2. Collect the elements to delete during iteration, then perform deletions after releasing the buffer.
  3. Wrap the iterator in an unmodifiable-tolerant algorithm, or copy to an ArrayList first if mutable iteration semantics are required.
  4. Catch UnsupportedOperationException if a shared utility may call remove(), and treat it as read-only.

Example fix

// before
while (iterator.hasNext()) {
    if (shouldDelete(iterator.next())) iterator.remove(); // UnsupportedOperationException
}

// after
List<Item> toDelete = new ArrayList<>();
while (iterator.hasNext()) {
    Item item = iterator.next();
    if (shouldDelete(item)) toDelete.add(item);
}
deleteItems(toDelete); // via the data source API
Defensive patterns

Strategy: type-guard

Validate before calling

// DataBufferIterator.remove always throws; treat buffers as read-only.
List<Item> snapshot = new ArrayList<>();
for (Item i : dataBuffer) snapshot.add(i); // safe copy for mutation logic

Type guard

boolean isRemovableIterator(java.util.Iterator<?> it) {
    return !(it instanceof DataBufferIterator);
}

Try / catch

try {
    iterator.remove();
} catch (UnsupportedOperationException e) {
    Log.w(TAG, "DataBuffer is read-only; delete via data source instead", e);
}

Prevention

When it happens

Trigger: Calling iterator.remove() inside any iteration over a DataBuffer (e.g. trying to 'delete' a row while looping); passing the iterator to code that mutates collections via Iterator.remove (like some removeAll/filter idioms).

Common situations: Developers assuming DataBuffer behaves like a mutable List; porting collection code that mutates during iteration; third-party utilities that call remove() opportunistically.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of microg/GmsCore@157c9d86ac (2026-09-06). Data as JSON: /api/errors/685198c064c84ec3. Report an issue: GitHub.