alibaba/Sentinel · error · IllegalStateException

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

Error message

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

What it means

StatEntryFuncMinMax rejects arraySet(long... values) with IllegalStateException. arraySet assigns values to indexed slots of an array-strategy entry; the min/max func has no slot array — only two AtomicReference<ValueRef> fields updated via compareAndSet — so the operation cannot be honored.

Source

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

    @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) { ; }
        }
        ValueRef lmin = min.get();
        if (lmin.value >= candidate) {
            final ValueRef cmin = new ValueRef(candidate, ref);
            while (!min.compareAndSet(lmin, cmin) && (lmin = min.get()).value >= candidate) { ; }

View on GitHub (pinned to a3f40ba8e9)

Solutions

  1. Replace the call with minMax(candidate, ref) for min/max entries.
  2. If slot overwrites are required, create an array-strategy entry.
  3. Validate type/method pairing in a one-shot smoke write at startup.

Example fix

// before
func.arraySet(slots); // minMax func -> throws

// after
for (int i = 0; i < slots.length; i++) { func.minMax(slots[i], "slot" + i); } // or use an array entry
Defensive patterns

Strategy: type-guard

Validate before calling

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

Type guard

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

Prevention

When it happens

Trigger: Calling arraySet(values) on a min/max entry — e.g. periodic snapshot code that overwrites slot values, pointed at a latency min/max metric by configuration error.

Common situations: Config mismatch between metric type and writer. Reuse of snapshot/overwrite emitters across metric kinds. Migration to min/max leaving stale arraySet call sites.

Related errors


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