{"record":{"id":"6e089bce5c41bb6b","repo":"apache/cassandra","slug":"invalid-duration-the-s-are-specified-multiple-ti","errorCode":null,"errorMessage":"Invalid duration. The %s are specified multiple times","messagePattern":"Invalid duration\\. The (.+?) are specified multiple times","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/cql3/functions/types/Duration.java","lineNumber":600,"sourceCode":"         */\n        private void validate(long units, long limit, String unitName)\n        {\n            checkArgument(\n            units <= limit,\n            \"Invalid duration. The total number of %s must be less or equal to %s\",\n            unitName,\n            Integer.MAX_VALUE);\n        }\n\n        /**\n         * Validates that the duration values are added in the proper order.\n         *\n         * @param unitIndex the unit index (e.g. years=1, months=2, ...)\n         */\n        private void validateOrder(int unitIndex)\n        {\n            if (unitIndex == currentUnitIndex)\n                throw new IllegalArgumentException(\n                String.format(\n                \"Invalid duration. The %s are specified multiple times\", getUnitName(unitIndex)));\n\n            if (unitIndex <= currentUnitIndex)\n                throw new IllegalArgumentException(\n                String.format(\n                \"Invalid duration. The %s should be after %s\",\n                getUnitName(currentUnitIndex), getUnitName(unitIndex)));\n\n            currentUnitIndex = unitIndex;\n        }\n\n        /**\n         * Returns the name of the unit corresponding to the specified index.\n         *\n         * @param unitIndex the unit index\n         * @return the name of the unit corresponding to the specified index.\n         */","sourceCodeStart":582,"sourceCodeEnd":618,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/cql3/functions/types/Duration.java#L582-L618","documentation":"Thrown by Duration.Builder.validateOrder when the same duration unit appears more than once in a single duration literal. The builder tracks the index of the last unit parsed; if the next unit has the same index, the units are duplicated. Duration syntax requires each unit to appear at most once.","triggerScenarios":"Parsing strings like Duration.from(\"1d 2d\") or \"1mo 2mo 3d\" — any duration where a unit symbol is repeated in one literal passed to Duration.from or a duration column insert.","commonSituations":"Programmatically building duration strings by concatenating components without deduplicating units; user input like '2 years 6 months 1 year'; template bugs that append the same unit twice.","solutions":["Remove the duplicate unit and merge its values (e.g. '1d 2d' -> '3d')","Pre-validate the duration string with a regex ensuring each unit appears at most once before calling Duration.from","Catch IllegalArgumentException and report which unit was duplicated to the user"],"exampleFix":"// before\nDuration.from(\"1y 6mo 1y\")\n// after\nDuration.from(\"2y 6mo\")","handlingStrategy":"validation","validationCode":"static boolean hasDuplicateUnits(String dur) {\n  java.util.regex.Matcher m = java.util.regex.Pattern.compile(\"(y|mo|w|d|h|m|s|ms|us|ns)\").matcher(dur);\n  java.util.Set<String> seen = new java.util.HashSet<>();\n  while (m.find()) { if (!seen.add(m.group())) return true; }\n  return false;\n}","typeGuard":null,"tryCatchPattern":"try { Duration d = Duration.from(input); } catch (IllegalArgumentException e) { throw new IllegalArgumentException(\"Malformed duration (duplicate/out-of-order units): \" + input, e); }","preventionTips":["Merge values per unit before building the duration string","When generating durations programmatically, use Duration.Builder-style accumulation instead of string concat","Reject duplicate units in input validation with a clear message"],"tags":["duration","parsing","duplicate-unit"],"backgroundTag":"invalid-duration-format","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}