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  map

View on GitHub (pinned to bf67d90747)

Solutions

  1. Inspect the stack trace to find which caller computed the negative size and fix that arithmetic (usually an underflow like a.length - b.length).
  2. Validate sizes derived from external/metadata input before passing them into collection helpers.
  3. 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

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.