{"record":{"id":"8001a1085bf3b2f5","repo":"apache/cassandra","slug":"unknown-duration-symbol-s-8001a1","errorCode":null,"errorMessage":"Unknown duration symbol '%s'","messagePattern":"Unknown duration symbol '(.+?)'","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/cql3/functions/types/Duration.java","lineNumber":282,"sourceCode":"            return builder.addMinutes(number);\n        }\n        else if (s.equals(\"s\"))\n        {\n            return builder.addSeconds(number);\n        }\n        else if (s.equals(\"ms\"))\n        {\n            return builder.addMillis(number);\n        }\n        else if (s.equals(\"us\") || s.equals(\"µs\"))\n        {\n            return builder.addMicros(number);\n        }\n        else if (s.equals(\"ns\"))\n        {\n            return builder.addNanos(number);\n        }\n        throw new IllegalArgumentException(String.format(\"Unknown duration symbol '%s'\", symbol));\n    }\n\n    /**\n     * Appends the result of the division to the specified builder if the dividend is not zero.\n     *\n     * @param builder  the builder to append to\n     * @param dividend the dividend\n     * @param divisor  the divisor\n     * @param unit     the time unit to append after the result of the division\n     * @return the remainder of the division\n     */\n    private static long append(StringBuilder builder, long dividend, long divisor, String unit)\n    {\n        if (dividend == 0 || dividend < divisor) return dividend;\n\n        builder.append(dividend / divisor).append(unit);\n        return dividend % divisor;\n    }","sourceCodeStart":264,"sourceCodeEnd":300,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/cql3/functions/types/Duration.java#L264-L300","documentation":"This IllegalArgumentException is thrown by Duration.Parser.add when a lowercase symbol token inside a CQL duration string is not one of the recognized unit symbols (y, mo, w, d, h, m, s, ms, us, ns, etc.). The parser only appends values when the symbol matches a known unit; anything else is rejected. It means the duration literal contains an unrecognized unit abbreviation.","triggerScenarios":"Calling Duration.from(\"1yr\") or any statement binding a duration literal with an unknown unit suffix; the parser splits the string into number/symbol pairs and hits a symbol not in its switch of recognized units.","commonSituations":"Typos in duration units ('2mnts', '5hrs'); confusing months ('mo') with minutes ('m'); using units like 'yr', 'sec', 'min' that are valid in human writing but not in the CQL duration grammar; copying durations from other libraries with different unit vocabularies.","solutions":["Fix the duration string to use only recognized symbols: y, mo, w, d, h, m, s, ms, us (or µs), ns","Remember 'm' is minutes and 'mo' is months; correct month/minute confusion","Wrap Duration.from in try-catch for IllegalArgumentException and surface a user-friendly message listing valid units"],"exampleFix":"// before\nDuration.from(\"2hrs 30min\")\n// after\nDuration.from(\"2h 30m\")","handlingStrategy":"validation","validationCode":"private static final Pattern DURATION_UNIT = Pattern.compile(\"^(\\\\d+)(y|mo|w|d|h|m|s|ms|us|µs|ns)$\");\nstatic boolean isValidDurationToken(String token) { return DURATION_UNIT.matcher(token).matches(); }\n// validate each number+unit pair of the duration string before Duration.from","typeGuard":null,"tryCatchPattern":"try { Duration d = Duration.from(input); } catch (IllegalArgumentException e) { throw new IllegalArgumentException(\"Invalid duration unit: \" + e.getMessage(), e); }","preventionTips":["Use only documented symbols: y, mo, w, d, h, m, s, ms, us, ns","Remember 'm' = minutes, 'mo' = months","Unit-test duration parsing with user-supplied literals","Normalize input from other libraries to CQL duration units first"],"tags":["duration","parsing","illegal-argument"],"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"}