{"id":"8e521516ca56b355","repo":"apache/kafka","slug":"must-specify-at-least-one-metric-name","errorCode":null,"errorMessage":"Must specify at least one metric name","messagePattern":"Must specify at least one metric name","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"clients/src/main/java/org/apache/kafka/common/metrics/stats/Frequencies.java","lineNumber":65,"sourceCode":"    /**\n     * Create a Frequencies instance with metrics for the frequency of a boolean sensor that records 0.0 for\n     * false and 1.0 for true.\n     *\n     * @param falseMetricName the name of the metric capturing the frequency of failures; may be null if not needed\n     * @param trueMetricName  the name of the metric capturing the frequency of successes; may be null if not needed\n     * @return the Frequencies instance; never null\n     * @throws IllegalArgumentException if both {@code falseMetricName} and {@code trueMetricName} are null\n     */\n    public static Frequencies forBooleanValues(MetricName falseMetricName, MetricName trueMetricName) {\n        List<Frequency> frequencies = new ArrayList<>();\n        if (falseMetricName != null) {\n            frequencies.add(new Frequency(falseMetricName, 0.0));\n        }\n        if (trueMetricName != null) {\n            frequencies.add(new Frequency(trueMetricName, 1.0));\n        }\n        if (frequencies.isEmpty()) {\n            throw new IllegalArgumentException(\"Must specify at least one metric name\");\n        }\n        Frequency[] frequencyArray = frequencies.toArray(new Frequency[0]);\n        return new Frequencies(2, 0.0, 1.0, frequencyArray);\n    }\n\n    private final Frequency[] frequencies;\n    private final BinScheme binScheme;\n\n    /**\n     * Create a Frequencies that captures the values in the specified range into the given number of buckets,\n     * where the buckets are centered around the minimum, maximum, and intermediate values.\n     *\n     * @param buckets     the number of buckets; must be at least 1\n     * @param min         the minimum value to be captured\n     * @param max         the maximum value to be captured\n     * @param frequencies the list of {@link Frequency} metrics, which at most should be one per bucket centered\n     *                    on the bucket's value, though not every bucket need to correspond to a metric if the\n     *                    value is not needed","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/apache/kafka/blob/c31c9215e131f8c17e79f8901b48c13ee6aa8e7a/clients/src/main/java/org/apache/kafka/common/metrics/stats/Frequencies.java#L47-L83","documentation":"Thrown by Frequencies.forBooleanValues when both the falseMetricName and trueMetricName arguments are null — the resulting Frequencies object would have zero Frequency metrics and therefore report nothing. forBooleanValues exists specifically to build a two-bucket boolean distribution; passing null for both is a misuse because the helper cannot construct a meaningful metric set.","triggerScenarios":"Calling Frequencies.forBooleanValues(null, null). This happens when both metric name arguments are conditionally computed and every branch evaluates to null, or when a caller passes a field that was never initialized.","commonSituations":"Building boolean frequencies from optional config where neither success nor failure metric was configured; refactoring that replaces a MetricName with null accidentally; defaulting method parameters to null without a fallback.","solutions":["Pass at least one non-null MetricName — typically both falseMetricName and trueMetricName for a boolean sensor.","If only one side is of interest, pass the other as null (allowed) but never both.","Validate inputs upstream (config presence) before calling forBooleanValues, and fail loudly with a clearer error if config is missing."],"exampleFix":"// before\nFrequencies.forBooleanValues(null, null); // throws\n// after\nFrequencies.forBooleanValues(\n    metrics.metricName(\"fail-rate\", ..., ...),\n    metrics.metricName(\"success-rate\", ..., ...)\n);","handlingStrategy":"validation","validationCode":"// Pre-validate before calling Frequencies.forBooleanValues(falseName, trueName):\nif (falseMetricName == null && trueMetricName == null) {\n    throw new IllegalArgumentException(\n        \"At least one of falseMetricName / trueMetricName must be non-null\");\n}\nreturn Frequencies.forBooleanValues(falseMetricName, trueMetricName);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always pass at least one non-null MetricName when modeling boolean frequencies.","If only one outcome matters to you (e.g. only successes), pass null for the other explicitly and document why.","Encapsulate the call behind a helper that fails fast with a domain-meaningful message."],"tags":["metrics","api-misuse","validation"],"analyzedSha":"c31c9215e131f8c17e79f8901b48c13ee6aa8e7a","analyzedAt":"2026-08-03T12:34:05.770Z","schemaVersion":2}