{"record":{"id":"e66d697eed5155a1","repo":"xuxueli/xxl-job","slug":"the-w-option-does-not-make-sense-with-values-lar","errorCode":null,"errorMessage":"The 'W' option does not make sense with values larger than 31 (max number of days in a month)","messagePattern":"The 'W' option does not make sense with values larger than 31 \\(max number of days in a month\\)","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":772,"sourceCode":"            if (type == DAY_OF_WEEK) {\n                if(val < 1 || val > 7)\n                    throw new ParseException(\"Day-of-Week values must be between 1 and 7\", -1);\n                lastDayOfWeek = true;\n            } else {\n                throw new ParseException(\"'L' option is not valid here. (pos=\" + i + \")\", i);\n            }\n            TreeSet<Integer> set = getSet(type);\n            set.add(val);\n            i++;\n            return i;\n        }\n\n        if (c == 'W') {\n            if (type != DAY_OF_MONTH) {\n                throw new ParseException(\"'W' option is not valid here. (pos=\" + i + \")\", i);\n            }\n            if(val > 31)\n                throw new ParseException(\"The 'W' option does not make sense with values larger than 31 (max number of days in a month)\", i);\n            nearestWeekdays.add(val);\n            i++;\n            return i;\n        }\n\n        if (c == '#') {\n            if (type != DAY_OF_WEEK) {\n                throw new ParseException(\"'#' option is not valid here. (pos=\" + i + \")\", i);\n            }\n            i++;\n            try {\n                nthDayOfWeek = Integer.parseInt(s.substring(i));\n                if (nthDayOfWeek < 1 || nthDayOfWeek > 5) {\n                    throw new Exception();\n                }\n            } catch (Exception e) {\n                throw new ParseException(\n                        \"A numeric value between 1 and 5 must follow the '#' option\",","sourceCodeStart":754,"sourceCodeEnd":790,"githubUrl":"https://github.com/xuxueli/xxl-job/blob/e74c784f68f81fa89cb350913ef15794865d7b12/xxl-job-admin/src/main/java/com/xxl/job/admin/business/scheduler/cron/CronExpression.java#L754-L790","documentation":"In checkNext, the 'W' (nearest weekday) modifier in the Day-of-Month field requires the preceding numeric value to be 31 or less, since no month has more than 31 days. This error fires when val > 31.","triggerScenarios":"A cron expression like '0 0 0 32W * ?' where the value before 'W' in the day-of-month field exceeds 31. The check at line 771 tests val > 31.","commonSituations":"Generating a day-of-month value dynamically without clamping, or a typo/overflow producing a value beyond 31.","solutions":["Reduce the day-of-month value to 31 or less before 'W'.","Validate the value against the 1-31 range before constructing the expression.","If the intent is the last weekday of the month, use 'LW' instead of a large number."],"exampleFix":"// before\n\"0 0 0 32W * ?\"\n// after\n\"0 0 0 15W * ?\"","handlingStrategy":"validation","validationCode":"// Check 'NW' value in day-of-month (field index 3) is <= 31\nString[] parts = cron.trim().split(\"\\\\s+\");\nif (parts.length > 3 && parts[3].matches(\".*\\\\d+W.*\")) {\n    String numPart = parts[3].replaceAll(\"W.*\", \"\").replaceAll(\".*[^0-9]\", \"\");\n    if (!numPart.isEmpty()) {\n        int val = Integer.parseInt(numPart);\n        if (val > 31) throw new IllegalArgumentException(\"'W' value must be <= 31: \" + val);\n    }\n}","typeGuard":"boolean isValidNearestWeekdayValue(String domField) {\n    if (!domField.contains(\"W\")) return true;\n    String num = domField.replaceAll(\"W.*\", \"\").replaceAll(\".*[^0-9]\", \"\");\n    if (num.isEmpty()) return true;\n    return Integer.parseInt(num) <= 31;","tryCatchPattern":"try {\n    new CronExpression(cron);\n} catch (ParseException e) {\n    if (e.getMessage().contains(\"'W' option does not make sense\")) {\n        // reduce the day value to 31 or less, or use 'LW' for last weekday\n    }\n}","preventionTips":["Clamp 'NW' values to 1-31 before building the expression.","For 'last weekday of the month', use 'LW' instead of a large number.","Validate day-of-month values against 1-31 in your cron builder."],"tags":["cron","validation","quartz","day-of-month"],"backgroundTag":null,"analyzedSha":"e74c784f68f81fa89cb350913ef15794865d7b12","analyzedAt":"2026-08-14T04:22:43.715Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}