{"record":{"id":"6f1fc4435885e45c","repo":"apache/cassandra","slug":"invalid-duration-the-s-should-be-after-s","errorCode":null,"errorMessage":"Invalid duration. The %s should be after %s","messagePattern":"Invalid duration\\. The (.+?) should be after (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/cql3/functions/types/Duration.java","lineNumber":605,"sourceCode":"            \"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         */\n        private String getUnitName(int unitIndex)\n        {\n            switch (unitIndex)\n            {\n                case 1:","sourceCodeStart":587,"sourceCodeEnd":623,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/cql3/functions/types/Duration.java#L587-L623","documentation":"Thrown by Duration.Builder.validateOrder when duration units appear out of descending order. The CQL duration grammar requires units from largest to smallest (years, months, weeks, days, hours, minutes, seconds, ...). If a unit's index is less than or equal to the previously parsed unit's index (and not a duplicate), the literal is invalid.","triggerScenarios":"Parsing strings like Duration.from(\"3d 1y\") or \"5s 2h\" — any literal where a smaller unit precedes a larger one, passed to Duration.from or used as a duration literal in CQL.","commonSituations":"Users writing durations in natural (ascending) order; i18n conventions where small units come first; code that sorts unit components alphabetically instead of by magnitude.","solutions":["Reorder the components from largest unit to smallest (e.g. '3d 1y' -> '1y 3d')","Split and sort the duration string by unit rank before passing it to Duration.from","Catch IllegalArgumentException and show the expected ordering rule to the user"],"exampleFix":"// before\nDuration.from(\"5s 2h 1d\")\n// after\nDuration.from(\"1d 2h 5s\")","handlingStrategy":"validation","validationCode":"private static final java.util.Map<String,Integer> RANK = java.util.Map.of(\"y\",1,\"mo\",2,\"w\",3,\"d\",4,\"h\",5,\"m\",6,\"s\",7,\"ms\",8,\"us\",9,\"ns\",10);\nstatic boolean unitsInOrder(String dur) {\n  java.util.List<Integer> r = new java.util.ArrayList<>();\n  java.util.regex.Matcher m = java.util.regex.Pattern.compile(\"(\\\\d+)(y|mo|w|d|h|m|s|ms|us|ns)\").matcher(dur);\n  while (m.find()) r.add(RANK.get(m.group(2)));\n  for (int i = 1; i < r.size(); i++) if (r.get(i) <= r.get(i-1)) return false;\n  return true;\n}","typeGuard":null,"tryCatchPattern":"try { Duration d = Duration.from(input); } catch (IllegalArgumentException e) { throw new IllegalArgumentException(\"Duration units must appear largest-to-smallest: \" + input, e); }","preventionTips":["Always write duration components largest to smallest: y, mo, w, d, h, m, s, ms, us, ns","Sort parsed components by unit rank before serialization","Display the ordering rule in any UI accepting duration input"],"tags":["duration","parsing","ordering"],"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"}