{"record":{"id":"4e98c165321462bb","repo":"apache/skywalking","slug":"the-length-of-buckets-and-values-should-be-same","errorCode":null,"errorMessage":"The length of buckets and values should be same.","messagePattern":"The length of buckets and values should be same\\.","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/function/BucketedValues.java","lineNumber":62,"sourceCode":"     * The {@link Long#MIN_VALUE} could be the first bucket element to indicate there is no minimal value.\n     */\n    private long[] buckets;\n    /**\n     * {@link #buckets} and {@link #values} arrays should have the same length. The element in the values, represents\n     * the amount in the same index bucket.\n     */\n    private long[] values;\n\n    /**\n     * @param buckets Read {@link #buckets}\n     * @param values  Read {@link #values}\n     */\n    public BucketedValues(final long[] buckets, final long[] values) {\n        if (buckets == null || values == null || buckets.length == 0 || values.length == 0) {\n            throw new IllegalArgumentException(\"buckets and values can't be null.\");\n        }\n        if (buckets.length != values.length) {\n            throw new IllegalArgumentException(\"The length of buckets and values should be same.\");\n        }\n        this.buckets = buckets;\n        this.values = values;\n    }\n\n    /**\n     * @return true if the bucket is same.\n     */\n    public boolean isCompatible(DataTable dataset) {\n        final List<String> sortedKeys = dataset.sortedKeys(new HeatMap.KeyComparator(true));\n        long[] existedBuckets = new long[sortedKeys.size()];\n        for (int i = 0; i < sortedKeys.size(); i++) {\n            String key = sortedKeys.get(i);\n            if (key.equals(Bucket.INFINITE_NEGATIVE)) {\n                existedBuckets[i] = Long.MIN_VALUE;\n            } else {\n                // remove the label name\n                if (key.contains(\":\")) {","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/apache/skywalking/blob/102af09b4a56064e22050dded10e2c52e490d040/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/function/BucketedValues.java#L44-L80","documentation":"BucketedValues pairs every bucket boundary with exactly one value (values[i] is the amount in buckets[i]); all iteration in histogram functions indexes both arrays in lockstep. The constructor therefore rejects arrays of different lengths with 'The length of buckets and values should be same.'","triggerScenarios":"A producer builds the bucket array from an explicit bucket list but the values array from observed counts, and a missing/extra bucket skews them; a MAL valueBuckets declaration with N boundaries is paired with N-1 or N+1 values; serialization/deserialization truncates one array.","commonSituations":"Off-by-one bugs computing buckets (boundary count vs bucket count); changing the buckets config in a MAL rule without regenerating the emitted values; custom agents packing histograms where the infinite-negative/positive sentinel buckets are mishandled.","solutions":["Make the producer derive both arrays from one source: values.length must equal buckets.length — typically buckets has one entry per bucket including the implicit infinity buckets","When bucket config changes, regenerate/redeploy the emitting side so it sends values matching the new bucket count","Add a boundary check in the sender (length equality) so the failure surfaces at the source, not in OAP"],"exampleFix":"// before\nlong[] buckets = {0, 10, 50, 100};          // 4 boundaries\nlong[] values  = {12, 8, 3};                 // 3 values -> throws\n\n// after\nlong[] buckets = {0, 10, 50, 100};\nlong[] values  = new long[buckets.length];   // always sized from buckets\n// fill values[i] by bucketing each observation","handlingStrategy":"validation","validationCode":"if (buckets.length != values.length) {\n    throw new IllegalStateException(\"buckets=\" + buckets.length + \" values=\" + values.length\n        + \" — bucket/value length mismatch at source for \" + metricName);\n}","typeGuard":"boolean sameLength(long[] a, long[] b) { return a != null && b != null && a.length == b.length; }","tryCatchPattern":null,"preventionTips":["Size the values array from the buckets array (values = new long[buckets.length]) rather than counting observations","Re-run producer tests after any change to bucket templates so length contracts stay locked","Log both lengths whenever a mismatch is detected at the producer to catch off-by-one bucket boundaries early"],"tags":["meter-system","histogram","validation","off-by-one","mal"],"backgroundTag":null,"analyzedSha":"102af09b4a56064e22050dded10e2c52e490d040","analyzedAt":"2026-08-14T10:47:52.647Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}