{"record":{"id":"52e679d35a0ab43c","repo":"xuxueli/xxl-job","slug":"w-option-is-not-valid-here-pos","errorCode":null,"errorMessage":"'W' option is not valid here. (pos={})","messagePattern":"'W' option is not valid here\\. \\(pos=(.+?)\\)","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":769,"sourceCode":"        char c = s.charAt(pos);\n\n        if (c == 'L') {\n            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                }","sourceCodeStart":751,"sourceCodeEnd":787,"githubUrl":"https://github.com/xuxueli/xxl-job/blob/e74c784f68f81fa89cb350913ef15794865d7b12/xxl-job-admin/src/main/java/com/xxl/job/admin/business/scheduler/cron/CronExpression.java#L751-L787","documentation":"In checkNext, the 'W' (nearest weekday) modifier following a numeric value is only valid in the Day-of-Month field. 'W' means 'the nearest weekday to day N of the month'. This error fires when 'W' appears after a number in any field other than day-of-month (e.g., day-of-week, hour, etc.).","triggerScenarios":"A cron expression like '0 0 0 ? * 5W' where '5W' appears in the day-of-week field. The parser reads 5 as a digit, enters checkNext, finds 'W', and since type != DAY_OF_MONTH, throws at line 769.","commonSituations":"Placing the 'W' modifier in the wrong field, or misunderstanding that 'W' is a day-of-month-only feature.","solutions":["Move the 'W' modifier and its preceding number to the day-of-month field: '0 0 0 15W * ?'.","If a weekday-based schedule is needed in day-of-week, use the appropriate day-of-week syntax (e.g., 'MON-FRI' or '1-5').","Confirm the field position matches Quartz's 6 or 7 field layout."],"exampleFix":"// before\n\"0 0 0 ? * 5W\"\n// after\n\"0 0 0 5W * ?\"","handlingStrategy":"validation","validationCode":"// 'NW' (number followed by W) is only valid in day-of-month (field index 3)\nString[] parts = cron.trim().split(\"\\\\s+\");\nfor (int idx = 0; idx < parts.length; idx++) {\n    if (parts[idx].matches(\".*\\\\d+W.*\") && idx != 3) {\n        throw new IllegalArgumentException(\"'NW' is only valid in day-of-month (field 3): \" + parts[idx]);\n    }\n}","typeGuard":"boolean isNumberWInDayOfMonthOnly(String[] parts) {\n    for (int idx = 0; idx < parts.length; idx++) {\n        if (parts[idx].matches(\".*\\\\d+W.*\") && idx != 3) return false;\n    }\n    return true;","tryCatchPattern":"try {\n    new CronExpression(cron);\n} catch (ParseException e) {\n    if (e.getMessage().contains(\"'W' option is not valid here\")) {\n        // move 'NW' to the day-of-month field\n    }\n}","preventionTips":["The 'W' (nearest weekday) modifier is day-of-month only.","For weekday-only schedules in day-of-week, use a range like '1-5' or 'MON-FRI'.","Verify field positions match the Quartz layout before submitting."],"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"}