alibaba/Sentinel · error · IllegalStateException

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

Error message

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

What it means

StatEntryFuncCountAndSum is the strategy implementation backing a stat entry created via countAndSum(): it tracks an occurrence count plus a summed value. Each StatEntryFunc supports exactly one statistical shape; once the entry is bound to countAndSum, calling the array-oriented arrayAdd(long... values) is a contract violation and throws IllegalStateException immediately.

Source

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

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

    @Override
    public void count(long count) {
        this.count.add(count);
    }

    @Override
    public void countAndSum(long count, long value) {
        this.count.add(count);
        this.value.add(value);
    }

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

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

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

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

    @Override

View on GitHub (pinned to a3f40ba8e9)

Solutions

  1. Align the write method with the entry's type: for count-and-sum entries call countAndSum(count, value) (or count(count)).
  2. If you truly need per-slot array accumulation, create the entry with the arrayAdd-compatible configuration instead of countAndSum.
  3. If a generic recorder must handle multiple entry types, dispatch on getStatType() before choosing the write method.

Example fix

// before
StatEntryFunc f = entry.getFunc(); // created via countAndSum
f.arrayAdd(v1, v2); // throws

// after
StatEntryFunc f = entry.getFunc();
f.countAndSum(1, v1); // matches the count-and-sum strategy
Defensive patterns

Strategy: type-guard

Validate before calling

if (func.getStatType() == 2 /* count-and-sum */) {
    func.countAndSum(1, value);
} // never call arrayAdd here

Type guard

boolean isCountAndSum(StatEntryFunc f) { return f.getStatType() == 2; }

Try / catch

try { func.arrayAdd(v); } catch (IllegalStateException e) { /* wrong strategy: fix the call site, do not swallow */ throw e; }

Prevention

When it happens

Trigger: An entry was created through statLogger... entry configured for count-and-sum (stat type where countAndSum is the supported op), then code calls entry.arrayAdd(values) — e.g. copy-pasted reporting code from an arrayAdd-based metric, or a generic recorder that switches strategy based on runtime config and picks the wrong method.

Common situations: A team copies metric-reporting code from another module that used arrayAdd. A generic monitoring wrapper decides at runtime which append method to call but the entry was created for a different stat type. Metric API migration where the entry type changed but not all call sites were updated.

Related errors


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