{"record":{"id":"edea669459589709","repo":"alibaba/Sentinel","slug":"keys-empty-or-null","errorCode":null,"errorMessage":"keys empty or null","messagePattern":"keys empty or null","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"sentinel-core/src/main/java/com/alibaba/csp/sentinel/eagleeye/StatEntry.java","lineNumber":91,"sourceCode":"        keys[0] = key1;\n        for (int i = 0; i < moreKeys.length; ++i) {\n            keys[i + 1] = moreKeys[i];\n        }\n        this.statLogger = statLogger;\n        this.keys = keys;\n    }\n\n    public StatEntry(StatLogger statLogger, List<String> keys) {\n        if (keys == null || keys.isEmpty()) {\n            throw new IllegalArgumentException(\"keys empty or null: \" + keys);\n        }\n        this.statLogger = statLogger;\n        this.keys = keys.toArray(new String[keys.size()]);\n    }\n\n    public StatEntry(StatLogger statLogger, String[] keys) {\n        if (keys == null || keys.length == 0) {\n            throw new IllegalArgumentException(\"keys empty or null\");\n        }\n        this.statLogger = statLogger;\n        this.keys = Arrays.copyOf(keys, keys.length);\n    }\n\n    public String[] getKeys() {\n        return keys;\n    }\n\n    void appendTo(StringBuilder appender, char delimiter) {\n        final int len = keys.length;\n        if (len > 0) {\n            appender.append(keys[0]);\n            for (int i = 1; i < len; ++i) {\n                appender.append(delimiter).append(keys[i]);\n            }\n        }\n    }","sourceCodeStart":73,"sourceCodeEnd":109,"githubUrl":"https://github.com/alibaba/Sentinel/blob/a3f40ba8e900c8489bd520274739f17235a7721c/sentinel-core/src/main/java/com/alibaba/csp/sentinel/eagleeye/StatEntry.java#L73-L109","documentation":"The array-based StatEntry constructor throws IllegalArgumentException when the keys array is null or has length 0. Keys are the dimension columns of an EagleEye stat row; without at least one key the row has no identity and cannot be serialized, so the constructor fails fast.","triggerScenarios":"Calling new StatEntry(statLogger, (String[]) null) or passing a zero-length String[] — e.g. an array produced by splitting an empty string (\"\".split(\",\") yields length-1 array but trim/filter steps can collapse it) or a varargs call like statLogger.stat() with no key argument.","commonSituations":"Keys are derived from splitting a config/URL string that is occasionally empty. A varargs forwarding helper passes an empty array when its own varargs list is empty. Arrays.asList conversion or list.toArray on an empty collection feeds a zero-length array.","solutions":["Guard the array for null/length==0 before constructing StatEntry; skip or substitute a default key such as \"-\".","Fix the upstream key derivation so an empty input cannot reach the constructor (validate the source string first).","Prefer the List constructor with an explicit isEmpty check, or the fixed-key varargs form, when the key set is static."],"exampleFix":"// before\nString[] keys = rawKeys.split(\",\");\nStatEntry e = statLogger.stat(keys); // throws when rawKeys is empty\n\n// after\nString[] keys = rawKeys.trim().isEmpty() ? new String[]{\"unknown\"} : rawKeys.split(\",\");\nStatEntry e = statLogger.stat(keys);","handlingStrategy":"validation","validationCode":"if (keys == null || keys.length == 0) {\n    // skip or substitute default key\n} else {\n    StatEntry entry = statLogger.stat(keys);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Guard every array produced by split() or toArray() before constructing StatEntry.","Write one shared helper statSafe(StatLogger, String...) that encapsulates the empty check.","Add unit tests covering empty and null key inputs."],"tags":["eagleeye","stat-entry","validation","illegal-argument","sentinel"],"backgroundTag":null,"analyzedSha":"a3f40ba8e900c8489bd520274739f17235a7721c","analyzedAt":"2026-08-14T11:10:30.678Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}