{"record":{"id":"e2b4f000d2ff11e6","repo":"xuxueli/xxl-job","slug":"l-not-expected-in-seconds-minutes-or-hours-fiel","errorCode":null,"errorMessage":"'L' not expected in seconds, minutes or hours fields.","messagePattern":"'L' not expected in seconds, minutes or hours fields\\.","errorType":"validation","errorClass":"ParseException","httpStatus":null,"severity":"error","filePath":"xxl-job-admin/src/main/java/com/xxl/job/admin/business/scheduler/cron/CronExpression.java","lineNumber":670,"sourceCode":"                }\n\n                incr = getNumericValue(s, i);\n\n                i++;\n                if (incr > 10) {\n                    i++;\n                }\n                checkIncrementRange(incr, type, i);\n            } else {\n                incr = 1;\n            }\n\n            addToSet(ALL_SPEC_INT, -1, incr, type);\n            return i;\n        } else if (c == 'L') {\n\n            if(type < DAY_OF_MONTH)\n                throw new ParseException(\"'L' not expected in seconds, minutes or hours fields.\", i);\n\n            i++;\n            if (type == DAY_OF_WEEK) {\n                addToSet(7, 7, 0, type);\n            }\n            if (type == DAY_OF_MONTH) {\n                int dom = LAST_DAY_OFFSET_END;\n                boolean nearestWeekday = false;\n                if (s.length() > i) {\n                    c = s.charAt(i);\n                    if (c == '-') {\n                        ValueSet vs = getValue(0, s, i + 1);\n                        int offset = vs.value;\n                        if (offset > MAX_LAST_DAY_OFFSET)\n                            throw new ParseException(\"Offset from last day must be <= \" + MAX_LAST_DAY_OFFSET, i + 1);\n                        dom -= offset;\n                        i = vs.pos;\n                    }","sourceCodeStart":652,"sourceCodeEnd":688,"githubUrl":"https://github.com/xuxueli/xxl-job/blob/e74c784f68f81fa89cb350913ef15794865d7b12/xxl-job-admin/src/main/java/com/xxl/job/admin/business/scheduler/cron/CronExpression.java#L652-L688","documentation":"The 'L' (last) modifier is only valid in the Day-of-Month and Day-of-Week fields. It means 'last day of the month' or 'last weekday of the month'. This error fires when 'L' appears in the seconds, minutes, or hours field (type < DAY_OF_MONTH, i.e., type 0, 1, or 2).","triggerScenarios":"A cron expression such as '0 0 8L * * ?' where 'L' appears in the hour field, or '0 0L * * * ?' in the minute field. The check at line 669 tests type < DAY_OF_MONTH (3).","commonSituations":"Misunderstanding the scope of the 'L' modifier, or a cron-generation tool that applies 'L' to the wrong field index. Developers familiar with non-Quartz cron may not expect 'L' to be field-restricted.","solutions":["Remove the 'L' from the seconds/minutes/hours field; use a plain number or '*'.","Move the 'L' logic to the day-of-month or day-of-week field where it is valid (e.g., '0 0 0 L * ?').","Review the Quartz cron field reference to confirm where 'L' is permitted."],"exampleFix":"// before\n\"0 0 8L * * ?\"\n// after\n\"0 8 0 L * ?\"","handlingStrategy":"validation","validationCode":"// 'L' may only appear in field index 3 (day-of-month) or 5 (day-of-week)\nString[] parts = cron.trim().split(\"\\\\s+\");\nfor (int idx = 0; idx < parts.length; idx++) {\n    if (parts[idx].contains(\"L\") && idx != 3 && idx != 5) {\n        throw new IllegalArgumentException(\"'L' is not valid in field \" + idx + \": \" + parts[idx]);\n    }\n}","typeGuard":"boolean isLInValidField(String[] parts) {\n    return (parts[0] == null || !parts[0].contains(\"L\"))\n        && (parts[1] == null || !parts[1].contains(\"L\"))\n        && (parts.length < 3 || !parts[2].contains(\"L\"));","tryCatchPattern":"try {\n    new CronExpression(cron);\n} catch (ParseException e) {\n    if (e.getMessage().contains(\"'L' not expected\")) {\n        // move 'L' to day-of-month or day-of-week\n    }\n}","preventionTips":["Remember 'L' only applies to the two day fields.","Document the valid scope of each cron modifier in your project's cron reference.","Add a pre-parse validation layer for user-entered cron strings."],"tags":["cron","validation","quartz"],"backgroundTag":null,"analyzedSha":"e74c784f68f81fa89cb350913ef15794865d7b12","analyzedAt":"2026-08-14T04:22:43.715Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}