{"record":{"id":"90ee69f3c55ffe89","repo":"alibaba/spring-cloud-alibaba","slug":"support-for-specifying-l-with-other-days-of-the","errorCode":null,"errorMessage":"Support for specifying 'L' with other days of the week is not implemented","messagePattern":"Support for specifying 'L' with other days of the week is not implemented","errorType":"exception","errorClass":"ParseException","httpStatus":null,"severity":"error","filePath":"spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-schedulerx/src/main/java/com/alibaba/cloud/scheduling/schedulerx/util/CronExpression.java","lineNumber":275,"sourceCode":"\t\t\tmonths = new TreeSet<>();\n\t\t\tdaysOfWeek = new TreeSet<>();\n\t\t\tyears = new TreeSet<>();\n\n\t\t\tint exprOn = SECOND;\n\n\t\t\tfinal StringTokenizer exprsTok = new StringTokenizer(expression, \" \\t\",\n\t\t\t\t\tfalse);\n\n\t\t\twhile (exprsTok.hasMoreTokens() && exprOn <= YEAR) {\n\t\t\t\tfinal String expr = exprsTok.nextToken().trim();\n\n\t\t\t\t// throw an exception if L is used with other days of the month\n\t\t\t\tif (exprOn == DAY_OF_MONTH && expr.indexOf('L') != -1 && expr.length() > 1 && expr.contains(\",\")) {\n\t\t\t\t\tthrow new ParseException(\"Support for specifying 'L' and 'LW' with other days of the month is not implemented\", -1);\n\t\t\t\t}\n\t\t\t\t// throw an exception if L is used with other days of the week\n\t\t\t\tif (exprOn == DAY_OF_WEEK && expr.indexOf('L') != -1 && expr.length() > 1 && expr.contains(\",\")) {\n\t\t\t\t\tthrow new ParseException(\"Support for specifying 'L' with other days of the week is not implemented\", -1);\n\t\t\t\t}\n\t\t\t\tif (exprOn == DAY_OF_WEEK && expr.indexOf('#') != -1 && expr.indexOf('#', expr.indexOf('#') + 1) != -1) {\n\t\t\t\t\tthrow new ParseException(\"Support for specifying multiple \\\"nth\\\" days is not implemented.\", -1);\n\t\t\t\t}\n\n\t\t\t\tfinal StringTokenizer vTok = new StringTokenizer(expr, \",\");\n\t\t\t\twhile (vTok.hasMoreTokens()) {\n\t\t\t\t\tfinal String v = vTok.nextToken();\n\t\t\t\t\tstoreExpressionVals(0, v, exprOn);\n\t\t\t\t}\n\n\t\t\t\texprOn++;\n\t\t\t}\n\n\t\t\tif (exprOn <= DAY_OF_WEEK) {\n\t\t\t\tthrow new ParseException(\"Unexpected end of expression.\",\n\t\t\t\t\t\texpression.length());\n\t\t\t}","sourceCodeStart":257,"sourceCodeEnd":293,"githubUrl":"https://github.com/alibaba/spring-cloud-alibaba/blob/115d5901102009492e05d5ec18c3f79cad4077d0/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-schedulerx/src/main/java/com/alibaba/cloud/scheduling/schedulerx/util/CronExpression.java#L257-L293","documentation":"Thrown during CronExpression.buildExpression while parsing the DAY_OF_WEEK field: if the token contains 'L' (e.g. '6L' = last Friday), is longer than one char, and also contains a comma, the parser throws ParseException. Quartz does not support mixing the 'last weekday of month' modifier with a list of other weekdays.","triggerScenarios":"A cron whose day-of-week field is a list including an L form, e.g. '0 0 0 ? * MON,6L'. The guard at CronExpression.java:273-275 matches DAY_OF_WEEK && indexOf('L')!=-1 && length()>1 && contains(',').","commonSituations":"Wanting 'every Monday and the last Friday' and writing 'MON,6L'; converting a natural-language schedule that bundles a weekly day with a 'last weekday' rule.","solutions":["Split into two triggers: one for the recurring weekday ('0 0 0 ? * MON') and one for the last-weekday rule ('0 0 0 ? * 6L').","If only the last weekday is needed, use the L form alone without a comma list.","Pre-validate all cron expressions at startup."],"exampleFix":"# before (invalid: L mixed in day-of-week list)\n0 0 0 ? * MON,6L\n\n# after (two triggers)\n0 0 0 ? * MON\n0 0 0 ? * 6L","handlingStrategy":"try-catch","validationCode":"static String validateCron(String cron) throws ParseException {\n    new com.alibaba.cloud.scheduling.schedulerx.util.CronExpression(cron);\n    return cron;\n}","typeGuard":"// reject day-of-week lists containing L before parsing\nstatic boolean isValidDow(String dow) {\n    boolean hasL = dow.indexOf('L') != -1;\n    return !(hasL && dow.length() > 1 && dow.contains(\",\"));\n}","tryCatchPattern":"try {\n    new CronExpression(cron);\n} catch (ParseException e) {\n    log.error(\"Bad day-of-week cron '{}': {}\", cron, e.getMessage());\n    throw e;\n}","preventionTips":["Do not mix 'L' (last weekday) with comma-separated weekdays; use multiple triggers.","Trial-parse crons during config validation so mistakes surface before runtime."],"tags":["java","schedulerx","cron","parsing","validation"],"backgroundTag":null,"analyzedSha":"115d5901102009492e05d5ec18c3f79cad4077d0","analyzedAt":"2026-08-14T04:47:13.900Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}