alibaba/Sentinel · error · IllegalStateException
minMax() is unavailable if countAndSum() has been called
Error message
minMax() is unavailable if countAndSum() has been called
What it means
minMax(long candidate, String ref) records the running maximum and minimum with an associated reference string — it belongs to the min/max strategy (StatEntryFuncMinMax), which stores two ValueRef slots. On a count-and-sum entry (StatEntryFuncCountAndSum) there is nowhere to store a min or max, so the call throws IllegalStateException.
Source
Thrown at sentinel-core/src/main/java/com/alibaba/csp/sentinel/eagleeye/StatEntryFunc.java:104
@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
public void strArray(String... values) {
throw new IllegalStateException("strArray() is unavailable if countAndSum() has been called");
}
}
class StatEntryFuncMinMax implements StatEntryFunc {
private AtomicReference<ValueRef> max = new AtomicReference<ValueRef>(new ValueRef(Long.MIN_VALUE, null));
private AtomicReference<ValueRef> min = new AtomicReference<ValueRef>(new ValueRef(Long.MAX_VALUE, null));
View on GitHub (pinned to a3f40ba8e9)
Solutions
- If you need min/max tracking, create the entry with the minMax strategy.
- If the entry is intentionally count-and-sum, replace minMax calls with countAndSum(1, value) and compute min/max downstream if needed.
- Dispatch on getStatType() (count-and-sum has its own type code, minMax is 4) in generic recorders.
Example fix
// before func.minMax(elapsedMs, resource); // func is StatEntryFuncCountAndSum -> throws // after func.countAndSum(1, elapsedMs); // aggregate sum/count; or create a minMax entry
Defensive patterns
Strategy: type-guard
Validate before calling
if (func.getStatType() == 4) { func.minMax(value, ref); } else { func.countAndSum(1, value); } Type guard
boolean isMinMax(StatEntryFunc f) { return f.getStatType() == 4; } Prevention
- Create dedicated min/max entries for latency metrics instead of reusing counters.
- Document the chosen strategy next to each entry definition.
- Dispatch on getStatType() in any shared recording utility.
When it happens
Trigger: Calling minMax(candidate, ref) on an entry created for countAndSum — e.g. mixing latency-tracking code (min/max pattern) with a counter/sum metric entry, or a shared recording utility that assumes every entry supports minMax.
Common situations: Latency or duration tracking code (classic min/max use case) is attached to a throughput counter entry. A generic stats facade forwards all recording styles to whatever entry it holds. Config-driven metric type changes without updating the recorder.
Related errors
- count() is unavailable if minMax() has been called
- countAndSum() is unavailable if minMax() has been called
- arrayAdd() is unavailable if minMax() has been called
- arraySet() is unavailable if minMax() has been called
- batchAdd() is unavailable if minMax() has been called
AI-assisted analysis of alibaba/Sentinel@a3f40ba8e9 (2026-08-14).
Data as JSON: /api/errors/a9d9457cc1f21f5d.
Report an issue: GitHub.