{"record":{"id":"b9be0dcb17da2efc","repo":"alibaba/Sentinel","slug":"strarray-is-unavailable-if-countandsum-has-bee","errorCode":null,"errorMessage":"strArray() is unavailable if countAndSum() has been called","messagePattern":"strArray\\(\\) is unavailable if countAndSum\\(\\) has been called","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"sentinel-core/src/main/java/com/alibaba/csp/sentinel/eagleeye/StatEntryFunc.java","lineNumber":114,"sourceCode":"\n    @Override\n    public void arraySet(long... values) {\n        throw new IllegalStateException(\"arraySet() is unavailable if countAndSum() has been called\");\n    }\n\n    @Override\n    public void minMax(long candidate, String ref) {\n        throw new IllegalStateException(\"minMax() is unavailable if countAndSum() has been called\");\n    }\n\n    @Override\n    public void batchAdd(long... values) {\n        throw new IllegalStateException(\"batchAdd() is unavailable if countAndSum() has been called\");\n    }\n\n    @Override\n    public void strArray(String... values) {\n        throw new IllegalStateException(\"strArray() is unavailable if countAndSum() has been called\");\n    }\n}\n\nclass StatEntryFuncMinMax implements StatEntryFunc {\n\n    private AtomicReference<ValueRef> max = new AtomicReference<ValueRef>(new ValueRef(Long.MIN_VALUE, null));\n    private AtomicReference<ValueRef> min = new AtomicReference<ValueRef>(new ValueRef(Long.MAX_VALUE, null));\n\n    @Override\n    public void appendTo(StringBuilder appender, char delimiter) {\n        ValueRef lmax = max.get();\n        ValueRef lmin = min.get();\n\n        appender.append(lmax.value).append(delimiter);\n        if (lmax.ref != null) {\n            appender.append(lmax.ref);\n        }\n        appender.append(delimiter);","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/alibaba/Sentinel/blob/a3f40ba8e900c8489bd520274739f17235a7721c/sentinel-core/src/main/java/com/alibaba/csp/sentinel/eagleeye/StatEntryFunc.java#L96-L132","documentation":"strArray(String... values) appends free-form string values to an entry and belongs to the string-array strategy. StatEntryFuncCountAndSum holds only two numeric AtomicLongs (count and value), has no storage for string values, and rejects the call with IllegalStateException.","triggerScenarios":"Calling strArray(labels) on an entry bound to the count-and-sum func — e.g. a tag/label logging call routed to a numeric counter entry, or a dynamically typed reporting pipeline that assumes every entry accepts strings.","commonSituations":"Adding dimension labels to a numeric metric and reusing the same entry. A logging utility overloaded for strings and numbers forwards both styles to one entry. Metric schema evolution where a numeric metric later needs string annotations.","solutions":["Use an entry configured for string values (strArray strategy) for label-style data.","Keep numeric metrics numeric: call countAndSum(1, numericValue).","If both are needed, create two entries in the same StatLogger with different key columns."],"exampleFix":"// before\nfunc.strArray(\"tagA\", \"tagB\"); // count-and-sum entry -> throws\n\n// after\n// numeric entry\nnumFunc.countAndSum(1, value);\n// separate string entry created for strArray\nstrFunc.strArray(\"tagA\", \"tagB\");","handlingStrategy":"type-guard","validationCode":"if (func.getStatType() == 2) {\n    func.countAndSum(1, numericValue); // never strArray here\n} else {\n    func.strArray(labels);\n}","typeGuard":"boolean isCountAndSum(StatEntryFunc f) { return f.getStatType() == 2; }","tryCatchPattern":null,"preventionTips":["Design metric schemas up front: numeric metrics never receive string values.","Use separate entries for labels vs numbers within the same StatLogger.","Centralize writes in typed recorder interfaces so string/numeric mistakes fail compilation."],"tags":["eagleeye","stat-func","api-misuse","illegal-state","string-values","sentinel"],"backgroundTag":null,"analyzedSha":"a3f40ba8e900c8489bd520274739f17235a7721c","analyzedAt":"2026-08-14T11:10:30.678Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}