{"record":{"id":"40b66e71fa2cef0c","repo":"pinpoint-apm/pinpoint","slug":"splitkeys-must-not-be-empty","errorCode":null,"errorMessage":"splitKeys must not be empty","messagePattern":"splitKeys must not be empty","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"hbase/hbase-schema/src/main/java/com/navercorp/pinpoint/hbase/schema/reader/core/CreateTableChange.java","lineNumber":64,"sourceCode":"\n        SplitOption NONE = new SplitOption() {\n            @Override\n            public byte[][] getSplitKeys() {\n                return new byte[0][];\n            }\n\n            @Override\n            public String toString() {\n                return \"NONE\";\n            }\n        };\n\n        class Manual implements SplitOption {\n            private final List<String> splitKeys;\n\n            public Manual(List<String> splitKeys) {\n                if (CollectionUtils.isEmpty(splitKeys)) {\n                    throw new IllegalArgumentException(\"splitKeys must not be empty\");\n                }\n                this.splitKeys = splitKeys;\n            }\n\n            @Override\n            public byte[][] getSplitKeys() {\n                byte[][] splits = new byte[splitKeys.size()][];\n                for (int i = 0; i < splitKeys.size(); i++) {\n                    splits[i] = Bytes.toBytesBinary(splitKeys.get(i));\n                }\n                return splits;\n            }\n\n            @Override\n            public boolean equals(Object o) {\n                if (this == o) return true;\n                if (o == null || getClass() != o.getClass()) return false;\n                Manual manual = (Manual) o;","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/pinpoint-apm/pinpoint/blob/744c3d3075e595656abb1ae331ad2c0e4c9eb996/hbase/hbase-schema/src/main/java/com/navercorp/pinpoint/hbase/schema/reader/core/CreateTableChange.java#L46-L82","documentation":"The Manual SplitOption for CreateTableChange validates that the provided list of split keys is non-empty. Creating a table with an explicit split-key list requires at least one key; an empty list would produce a table with no region splits. The library rejects this at construction time.","triggerScenarios":"Calling new CreateTableChange.SplitOption.Manual(Collections.emptyList()) or Manual(list) where list is null/empty, e.g. building a CreateTableChange with a manual split strategy but no keys.","commonSituations":"Split keys loaded from a config file or resource that is empty; a caller that computed keys dynamically (e.g. from rowkey ranges) and got zero results; copy-paste of Manual option without filling keys.","solutions":["Provide at least one split key to Manual(...)","If the number of regions is unknown, use the Auto(numRegions) split option instead","If no splitting is intended, pass the no-split option rather than Manual with an empty list","Validate the source of split keys (config/DB) so an empty result surfaces before table creation"],"exampleFix":"// before\nSplitOption option = new SplitOption.Manual(Collections.emptyList());\n// after\nSplitOption option = new SplitOption.Auto(8); // or Manual(Arrays.asList(\"key1\", \"key2\"))","handlingStrategy":"validation","validationCode":"if (splitKeys == null || splitKeys.isEmpty()) {\n    throw new IllegalArgumentException(\"Provide at least one split key\");\n}\nnew CreateTableChange.SplitOption.Manual(splitKeys);","typeGuard":"boolean hasSplitKeys(List<String> keys) {\n    return keys != null && !keys.isEmpty();\n}","tryCatchPattern":"try {\n    SplitOption opt = new CreateTableChange.SplitOption.Manual(keys);\n} catch (IllegalArgumentException e) {\n    // fall back to no-split or Auto\n    opt = new CreateTableChange.SplitOption.Auto(4);\n}","preventionTips":["Validate split-key sources (config files, ranges) before constructing Manual","Use Auto(numRegions) when key distribution is unknown","Never construct Manual from a possibly-empty dynamic list without a guard"],"tags":["hbase","schema","split-keys","illegal-argument"],"backgroundTag":"empty-required-field","analyzedSha":"744c3d3075e595656abb1ae331ad2c0e4c9eb996","analyzedAt":"2026-09-07T18:48:45.289Z","contentChangedAt":"2026-09-07T18:48:45.289Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}