{"record":{"id":"689be6bc674044e8","repo":"xuxueli/xxl-job","slug":"hour-values-must-be-between-0-and-23","errorCode":null,"errorMessage":"Hour values must be between 0 and 23","messagePattern":"Hour values must be between 0 and 23","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":994,"sourceCode":"        }\n\n        return i;\n    }\n\n    protected void addToSet(int val, int end, int incr, int type)\n            throws ParseException {\n\n        TreeSet<Integer> set = getSet(type);\n\n        if (type == SECOND || type == MINUTE) {\n            if ((val < 0 || val > 59 || end > 59) && (val != ALL_SPEC_INT)) {\n                throw new ParseException(\n                        \"Minute and Second values must be between 0 and 59\",\n                        -1);\n            }\n        } else if (type == HOUR) {\n            if ((val < 0 || val > 23 || end > 23) && (val != ALL_SPEC_INT)) {\n                throw new ParseException(\n                        \"Hour values must be between 0 and 23\", -1);\n            }\n        } else if (type == DAY_OF_MONTH) {\n            if ((val < 1 || val > 31 || end > 31) && (val != ALL_SPEC_INT)\n                    && (val != NO_SPEC_INT)) {\n                throw new ParseException(\n                        \"Day of month values must be between 1 and 31\", -1);\n            }\n        } else if (type == MONTH) {\n            if ((val < 1 || val > 12 || end > 12) && (val != ALL_SPEC_INT)) {\n                throw new ParseException(\n                        \"Month values must be between 1 and 12\", -1);\n            }\n        } else if (type == DAY_OF_WEEK) {\n            if ((val == 0 || val > 7 || end > 7) && (val != ALL_SPEC_INT)\n                    && (val != NO_SPEC_INT)) {\n                throw new ParseException(\n                        \"Day-of-Week values must be between 1 and 7\", -1);","sourceCodeStart":976,"sourceCodeEnd":1012,"githubUrl":"https://github.com/xuxueli/xxl-job/blob/e74c784f68f81fa89cb350913ef15794865d7b12/xxl-job-admin/src/main/java/com/xxl/job/admin/business/scheduler/cron/CronExpression.java#L976-L1012","documentation":"Thrown by CronExpression's field-validation routine (addToSet) when the HOUR token of a cron expression contains a value below 0 or above 23, or a range whose upper bound exceeds 23. The '*' wildcard is stored internally as ALL_SPEC_INT (99) and is exempt, so every literal hour must fall in the inclusive range 0-23.","triggerScenarios":"Constructing new CronExpression(\"0 0 24 * * ?\"), or any HOUR field with a literal >23 or <0, a range like \"0-26\", or a step value whose computed value exceeds 23. Triggered during CronExpression construction (parsing), before the expression is ever used to compute a fire time.","commonSituations":"Assuming a 1-24 hour clock and typing 24 for midnight (should be 0); migrating schedules from tools that use 1-based hours; dynamically generating cron strings with an off-by-one error in the hour computation.","solutions":["Replace any hour literal outside 0-23 with a valid value; midnight is 0, not 24.","If every hour is intended, keep the '*' wildcard instead of an explicit list.","Unit-test generated/stored cron strings by constructing CronExpression in a test before persisting them."],"exampleFix":"// before\nnew CronExpression(\"0 0 24 * * ?\"); // 24 is out of range\n// after\nnew CronExpression(\"0 0 0 * * ?\"); // midnight = 0","handlingStrategy":"validation","validationCode":"// Reject out-of-range HOUR before building CronExpression\nString expr = \"0 0 24 * * ?\";\nString[] f = expr.trim().split(\"\\\\s+\");\nString hourField = (f.length >= 6) ? f[2] : f[1]; // hour position in 5- or 6-field cron\n// cheap literal guard; ranges/steps still need a full parse\nif (hourField.matches(\"\\\\d+\") ) {\n    int h = Integer.parseInt(hourField);\n    if (h < 0 || h > 23) throw new IllegalArgumentException(\"hour out of range: \" + h);\n}","typeGuard":null,"tryCatchPattern":"try {\n    CronExpression c = new CronExpression(expr);\n} catch (java.text.ParseException e) {\n    log.warn(\"Invalid cron '{}': {}\", expr, e.getMessage());\n}","preventionTips":["Treat cron HOUR as 0-based 0-23; midnight is 0 not 24.","Unit-test every generated cron string with new CronExpression(expr).","Never assemble cron strings from unchecked user input."],"tags":["cron","validation","configuration","parse"],"backgroundTag":null,"analyzedSha":"e74c784f68f81fa89cb350913ef15794865d7b12","analyzedAt":"2026-08-14T04:22:43.715Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}