alibaba/Sentinel · error · IllegalStateException

arrayAdd() is unavailable if minMax() has been called

Error message

arrayAdd() is unavailable if minMax() has been called

What it means

On StatEntryFuncMinMax, arrayAdd(long... values) throws IllegalStateException. The array-add strategy requires a fixed-length slot array; the min/max func only holds two single-value references (max and min), so array accumulation is structurally impossible.

Source

Thrown at sentinel-core/src/main/java/com/alibaba/csp/sentinel/eagleeye/StatEntryFunc.java:164

    @Override
    public int getStatType() {
        return 4;
    }

    @Override
    public void count(long count) {
        throw new IllegalStateException("count() is unavailable if minMax() has been called");
    }

    @Override
    public void countAndSum(long count, long value) {
        throw new IllegalStateException("countAndSum() is unavailable if minMax() has been called");
    }

    @Override
    public void arrayAdd(long... values) {
        throw new IllegalStateException("arrayAdd() is unavailable if minMax() has been called");
    }

    @Override
    public void arraySet(long... values) {
        throw new IllegalStateException("arraySet() is unavailable if minMax() has been called");
    }

    @Override
    public void batchAdd(long... values) {
        throw new IllegalStateException("batchAdd() is unavailable if minMax() has been called");
    }

    @Override
    public void minMax(long candidate, String ref) {
        ValueRef lmax = max.get();
        if (lmax.value <= candidate) {
            final ValueRef cmax = new ValueRef(candidate, ref);
            while (!max.compareAndSet(lmax, cmax) && (lmax = max.get()).value <= candidate) { ; }

View on GitHub (pinned to a3f40ba8e9)

Solutions

  1. Use minMax(candidate, ref) for min/max entries; use a dedicated array-type entry for arrayAdd.
  2. Split the metric into two entries if both shapes are needed.
  3. Gate the writer with a getStatType() check in shared emitters.

Example fix

// before
func.arrayAdd(v1, v2, v3); // minMax func -> throws

// after
func.minMax(v1, ref);
Defensive patterns

Strategy: type-guard

Validate before calling

if (func.getStatType() == 4) { func.minMax(value, ref); } else { func.arrayAdd(values); }

Type guard

boolean isMinMax(StatEntryFunc f) { return f.getStatType() == 4; }

Prevention

When it happens

Trigger: Calling arrayAdd(values) on an entry created with the minMax strategy — typically array-style reporting code applied to a latency min/max metric, or a config mismatch between metric type and emitter method.

Common situations: Array-based dashboards retrofitted onto min/max metrics. Config-driven metric types changed after emitters were written. Shared emitter code across heterogeneous metrics.

Related errors


AI-assisted analysis of alibaba/Sentinel@a3f40ba8e9 (2026-08-14). Data as JSON: /api/errors/da15ab24583638d3. Report an issue: GitHub.