Skip to content
java.lang.UnsupportedOperationException

java.lang.UnsupportedOperationException

DodaTech 3 min read

java.lang.UnsupportedOperationException in Kotlin occurs when you call add() or remove() on a read-only collection created with listOf() or similar.

What It Means

Kotlin distinguishes between read-only collections (List, Set, Map) and mutable collections (MutableList, MutableSet, MutableMap). Read-only collections do not expose modification methods at compile time — but some underlying Java implementations (like Arrays.asList() or listOf()) do have add()/remove() at runtime via JVM interop, and calling them throws UnsupportedOperationException.

Why It Happens

  • You used listOf() and then called .add() on the result — listOf() returns a read-only List.
  • You converted a List to MutableList using .toMutableList() but still used the original reference.
  • You called Arrays.asList() (Java interop) then tried to add or remove elements.
  • You used Collections.unmodifiableList() or similar Java wrapper.
  • You called .asList() on an array — the returned list is backed by the array and doesn’t support structural modification.

How to Fix It

1. Use mutableListOf() instead of listOf()

// ❌ UnsupportedOperationException
val items = listOf("a", "b", "c")
items.add("d")

// ✅ Use a mutable collection
val items = mutableListOf("a", "b", "c")
items.add("d") // works fine

2. Convert a read-only list to mutable when needed

// If you receive a List from an API, convert it:
fun process(input: List<String>) {
    // ❌ input.add("new") — UnsupportedOperationException
    val mutable = input.toMutableList()
    mutable.add("new") // ✅ OK
}

3. Declare the correct collection type

// ❌ Declared as List but need add/remove
class ShoppingCart {
    val items: List<String> = mutableListOf() // exposed as read-only

    fun addItem(item: String) {
        items.add(item) // UnsupportedOperationException at runtime
    }
}

// ✅ Store as MutableList internally
class ShoppingCart {
    private val _items = mutableListOf<String>()
    val items: List<String> get() = _items // expose read-only

    fun addItem(item: String) {
        _items.add(item)
    }
}

4. Avoid Arrays.asList() for mutable operations

// ❌ Arrays.asList() returns a fixed-size list
val list = Arrays.asList("a", "b", "c")
list.add("d") // UnsupportedOperationException

// ✅ Use mutableListOf or ArrayList directly
val list = mutableListOf("a", "b", "c")
list.add("d")

5. Use toMutableList() for defensive copies

class Team {
    private val members = mutableListOf("Alice", "Bob")

    // Return a mutable copy so callers can modify without affecting internal state
    fun getMembers(): MutableList<String> = members.toMutableList()
}
What’s the difference between List and MutableList in Kotlin?
List is a read-only interface with size, get(), contains() — but no add() or remove(). MutableList extends List and adds mutation methods. The actual runtime object may be the same Java ArrayList either way; the difference is what operations the compiler allows.
Does listOf() always return an immutable list?
listOf() returns a List implementation that does not support modification. In the JVM, it often returns Arrays.ArrayList (a fixed-size wrapper), not java.util.ArrayList. Calling add() on it always throws UnsupportedOperationException.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro