google/gson · error · ClassCastException
{className} is not Comparable
Error message
{className} is not Comparable What it means
Thrown by LinkedTreeMap.find() as a ClassCastException ('<className> is not Comparable') when the map is using natural ordering (no comparator supplied) and the first key inserted does not implement Comparable. LinkedTreeMap orders keys via compareTo; without a Comparator and without Comparable keys it has no way to position nodes, so it rejects the key rather than producing undefined ordering.
Source
Thrown at gson/src/main/java/com/google/gson/internal/LinkedTreeMap.java:184
break;
}
nearest = child;
}
}
// The key doesn't exist in this tree.
if (!create) {
return null;
}
// Create the node and add it to the tree or the table.
Node<K, V> header = this.header;
Node<K, V> created;
if (nearest == null) {
// Check that the value is comparable if we didn't do any comparisons.
if (comparator == null && !(key instanceof Comparable)) {
throw new ClassCastException(key.getClass().getName() + " is not Comparable");
}
created = new Node<>(allowNullValues, nearest, key, header, header.prev);
root = created;
} else {
created = new Node<>(allowNullValues, nearest, key, header, header.prev);
if (comparison < 0) { // nearest.key is higher
nearest.left = created;
} else { // comparison > 0, nearest.key is lower
nearest.right = created;
}
rebalance(nearest, true);
}
size++;
modCount++;
return created;
}
View on GitHub (pinned to 8b8628c656)
Solutions
- Make the key class implement Comparable and implement compareTo consistently with equals.
- Supply a Comparator when creating the map: new LinkedTreeMap<>(myComparator, true).
- Use a HashMap/LinkedHashMap if you only need hash-based keys and do not require ordering.
Example fix
// before
class Key { String id; } // not Comparable
LinkedTreeMap<Key, Integer> m = new LinkedTreeMap<>();
m.put(new Key(), 1); // throws
// after: implement Comparable
class Key implements Comparable<Key> {
public int compareTo(Key o) { return id.compareTo(o.id); }
} Defensive patterns
Strategy: type-guard
Validate before calling
static boolean isComparableKey(Object key) {
return key instanceof Comparable;
}
// usage: if (!isComparableKey(k)) throw new IllegalArgumentException("key must be Comparable"); Type guard
static <K> boolean keyTypeIsComparable(Class<K> type) {
return Comparable.class.isAssignableFrom(type);
} Try / catch
try {
map.put(key, value);
} catch (ClassCastException e) {
if (e.getMessage().contains("not Comparable")) {
// rebuild the map with an explicit Comparator and retry
map = new LinkedTreeMap<>(myComparator, map.allowNullValues);
} else throw e;
} Prevention
- Ensure key types implement Comparable, or supply a Comparator.
- Use HashMap when ordering is not required.
- Validate key class implements Comparable at construction time for natural-order maps.
When it happens
Trigger: Calling put(key, value) where key's class does not implement Comparable, on a LinkedTreeMap created with the no-arg or LinkedTreeMap(boolean) constructors (natural order). The check only fires on the first insertion because that is the first time a comparison would be attempted.
Common situations: Using a POJO/domain class as a map key without implementing Comparable; Gson deserializing into a Map<MyPojo, V> where MyPojo is not Comparable; mixing key types inadvertently.
Related errors
- key == null
- value == null
- Deserialization is unsupported
- Element must be non-null
- Invalid style: {style}
AI-assisted analysis of google/gson@8b8628c656 (2026-08-04).
Data as JSON: /data/errors/89cab2c91d5b33f6.json.
Report an issue: GitHub.