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
- Replace the call with minMax(candidate, ref) for min/max entries.
- If slot overwrites are required, create an array-strategy entry.
- 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
- Snapshot/overwrite emitters must be bound only to array-strategy entries.
- Check the stat type before any arraySet call in shared code.
- Start each deployment with a canary write per metric.
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
- arrayAdd() is unavailable if minMax() has been called
- minMax() is unavailable if countAndSum() has been called
- count() is unavailable if minMax() has been called
- countAndSum() 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/ee98138c342d5efd.
Report an issue: GitHub.