{"record":{"id":"16238530564bf1de","repo":"flowable/flowable-engine","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":"exception","errorClass":"ParseException","httpStatus":null,"severity":"error","filePath":"modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/calendar/CronExpression.java","lineNumber":757,"sourceCode":"                }\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                nearestWeekday = true;\n            } else {\n                throw new ParseException(\"'W' option is not valid here. (pos=\" + i + \")\", i);\n            }\n            if (val > 31) {\n                throw new ParseException(\n                        \"The 'W' option does not make sense with values larger than 31 (max number of days in a month)\",\n                        i);\n            }\n            TreeSet<Integer> set = getSet(type);\n            set.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();","sourceCodeStart":739,"sourceCodeEnd":775,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/calendar/CronExpression.java#L739-L775","documentation":"checkNext validates that a day-of-month value used with the 'W' (nearest weekday) option is at most 31. Since no month has more than 31 days, '32W' or higher is meaningless and throws this ParseException.","triggerScenarios":"Expressions like \"0 0 0 32W * ?\" where the value before 'W' exceeds 31.","commonSituations":"Off-by-one or 'last day' attempts (users writing 32W intending end-of-month); generated expressions with unclamped day values.","solutions":["Use a day value 1-31 with W (e.g. 31W)","Use 'L' alone or 'LW' for last-day / last-weekday-of-month semantics","Clamp day-of-month inputs before constructing the CronExpression"],"exampleFix":"// before\nnew CronExpression(\"0 0 0 32W * ?\");\n// after\nnew CronExpression(\"0 0 0 LW * ?\"); // last weekday of month","handlingStrategy":"validation","validationCode":"boolean validNW(String domField) {\n    if (!domField.matches(\"\\\\d+W\")) return true;\n    int d = Integer.parseInt(domField.substring(0, domField.length() - 1));\n    return d >= 1 && d <= 31;\n}","typeGuard":null,"tryCatchPattern":"try {\n    CronExpression cron = new CronExpression(expr);\n} catch (ParseException e) {\n    if (e.getMessage().contains(\"'W' option does not make sense\")) {\n        throw new ConfigurationException(\"nW day value must be 1-31: \" + expr, e);\n    }\n    throw e;\n}","preventionTips":["Clamp day-of-month values to 1-31 before appending W","Use L or LW for end-of-month semantics instead of 31W/32W attempts","Validate generated expressions in CI"],"tags":["cron","w-option","quartz","value-out-of-range"],"backgroundTag":"value-out-of-range","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-18T11:17:12.947Z"}