baomidou/mybatis-plus · error · IllegalArgumentException
expectedSize cannot be negative but was: {}
Error message
expectedSize cannot be negative but was: {} What it means
CollectionUtils.capacity(expectedSize) computes an initial HashMap capacity for an expected size (mirroring Guava's Maps.capacity). If expectedSize is negative it throws IllegalArgumentException('expectedSize cannot be negative but was: N'). Callers reach it via collection helpers that size a new map from a computed length; a negative computed size is always a bug in the calling arithmetic or corrupt input.
Source
Thrown at mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/toolkit/CollectionUtils.java:176
return v;
} else {
return concurrentHashMap.computeIfAbsent(key, mappingFunction);
}
}
/**
* Returns a capacity that is sufficient to keep the map from being resized as
* long as it grows no larger than expectedSize and the load factor is >= its
* default (0.75).
*
* @see com.google.common.collect.Maps#capacity(int)
* @since 3.4.0
*/
private static int capacity(int expectedSize) {
if (expectedSize < 3) {
if (expectedSize < 0) {
throw new IllegalArgumentException("expectedSize cannot be negative but was: " + expectedSize);
}
return expectedSize + 1;
}
if (expectedSize < MAX_POWER_OF_TWO) {
// This is the calculation used in JDK8 to resize when a putAll
// happens; it seems to be the most conservative calculation we
// can make. 0.75 is the default load factor.
return (int) ((float) expectedSize / 0.75F + 1.0F);
}
return Integer.MAX_VALUE; // any large value
}
// 提供处理Map多key取值工具方法
/**
* 批量取出Map中的值
*
* @param map mapView on GitHub (pinned to bf67d90747)
Solutions
- Inspect the stack trace to find which caller computed the negative size and fix that arithmetic (usually an underflow like a.length - b.length).
- Validate sizes derived from external/metadata input before passing them into collection helpers.
- If you copied this helper into your own code, reject negative sizes at your API boundary instead of deep inside capacity().
Example fix
// before int expected = first.length - skipCount; // skipCount > first.length -> negative Map<String, Field> m = new LinkedHashMap<>(CollectionUtils.capacity(expected)); // after int expected = Math.max(0, first.length - skipCount); Map<String, Field> m = new LinkedHashMap<>(expected);
Defensive patterns
Strategy: validation
Validate before calling
int expected = computeExpectedSize();
if (expected < 0) {
throw new IllegalArgumentException("expectedSize computed negative: " + expected);
}
Map<String, Field> m = new LinkedHashMap<>(expected); Try / catch
try {
Map<String, Field> m = new LinkedHashMap<>(CollectionUtils.capacity(size));
} catch (IllegalArgumentException e) {
throw new IllegalStateException("size computation bug: " + size, e);
} Prevention
- Never derive map sizes by unchecked subtraction; clamp with Math.max(0, ...).
- Treat sizes coming from metadata or external input as untrusted and bound-check them at the boundary.
When it happens
Trigger: Passing a negative expected size into the internal capacity() path, e.g. a collection helper invoked with a size derived from a subtraction or an array length that came out negative. Since capacity() is private, the practical trigger is a public CollectionUtils method (map-sized helpers introduced in 3.4.0) receiving a negative size from user-supplied data.
Common situations: Entity metadata with negative counts (e.g. field count computed by subtraction returning negative); copying mybatis-plus internals into user code and calling capacity with unchecked input; extremely rare in normal use because public APIs usually pass array lengths which cannot be negative.
Related errors
AI-assisted analysis of baomidou/mybatis-plus@bf67d90747 (2026-08-14).
Data as JSON: /api/errors/b6d120e57dcb1da9.
Report an issue: GitHub.