{"record":{"id":"e6ab79eb644aa918","repo":"jeecgboot/JeecgBoot","slug":"increment-60-incr","errorCode":null,"errorMessage":"Increment >= 60 : {incr}","messagePattern":"Increment >= 60 : (.+?)","errorType":"exception","errorClass":"ParseException","httpStatus":null,"severity":"error","filePath":"jeecg-boot/jeecg-server-cloud/jeecg-visual/jeecg-cloud-xxljob/src/main/java/com/xxl/job/admin/business/scheduler/cron/CronExpression.java","lineNumber":728,"sourceCode":"                c = s.charAt(i);\n                if (c >= '0' && c <= '9') {\n                    ValueSet vs = getValue(val, s, i);\n                    val = vs.value;\n                    i = vs.pos;\n                }\n                i = checkNext(i, s, val, type);\n                return i;\n            }\n        } else {\n            throw new ParseException(\"Unexpected character: \" + c, i);\n        }\n\n        return i;\n    }\n\n    private void checkIncrementRange(int incr, int type, int idxPos) throws ParseException {\n        if (incr > 59 && (type == SECOND || type == MINUTE)) {\n            throw new ParseException(\"Increment >= 60 : \" + incr, idxPos);\n        } else if (incr > 23 && (type == HOUR)) {\n            throw new ParseException(\"Increment >= 24 : \" + incr, idxPos);\n        } else if (incr > 31 && (type == DAY_OF_MONTH)) {\n            throw new ParseException(\"Increment >= 31 : \" + incr, idxPos);\n        } else if (incr > 7 && (type == DAY_OF_WEEK)) {\n            throw new ParseException(\"Increment >= 7 : \" + incr, idxPos);\n        } else if (incr > 12 && (type == MONTH)) {\n            throw new ParseException(\"Increment >= 12 : \" + incr, idxPos);\n        }\n    }\n\n    protected int checkNext(int pos, String s, int val, int type)\n            throws ParseException {\n\n        int end = -1;\n        int i = pos;\n\n        if (i >= s.length()) {","sourceCodeStart":710,"sourceCodeEnd":746,"githubUrl":"https://github.com/jeecgboot/JeecgBoot/blob/96fb33f5ec68516da0b0147da06b2eb0419e063a/jeecg-boot/jeecg-server-cloud/jeecg-visual/jeecg-cloud-xxljob/src/main/java/com/xxl/job/admin/business/scheduler/cron/CronExpression.java#L710-L746","documentation":"checkIncrementRange rejects a step value greater than 59 for SECOND or MINUTE fields, since those fields max out at 59. A step like '/60' or '/120' is meaningless and throws. The message echoes the offending increment. The function is called from the '/' handling after the increment is parsed.","triggerScenarios":"Seconds or minutes step out of range: '0/60 * * * * ?' (SECOND), '0 0/70 * * * ?' (MINUTE), or an expression builder that computes a step > 59 for these fields.","commonSituations":"Confusing minutes with seconds (e.g. '/120' to mean 'every 2 minutes' but placed in the seconds field); dynamic step generation without per-field bounds; typo adding a digit.","solutions":["Cap second/minute steps at 59; use '/30', '/15', '/10' for common intervals.","If you meant minutes, move the step to the minute field (second field '0 0/2 * * * ?' = every 2 minutes).","When generating steps, clamp to the field's maximum (59 for sec/min, 23 for hour, 31 dom, 7 dow, 12 month)."],"exampleFix":"// before - seconds step > 59\nString cron = \"0/120 * * * * ?\";  // Increment >= 60 : 120\n\n// after - every 2 minutes (step in minute field)\nString cron = \"0 0/2 * * * ?\";","handlingStrategy":"validation","validationCode":"// Field maxima for step validation: SECOND/MINUTE=59.\npublic static String validateStepRange(String field, int fieldMax) {\n    if (field == null || !field.contains(\"/\")) return null;\n    try {\n        String stepPart = field.substring(field.indexOf('/') + 1).replaceAll(\"[^0-9]\", \"\");\n        int step = Integer.parseInt(stepPart);\n        if (step > fieldMax) return \"step \" + step + \" exceeds field max \" + fieldMax;\n    } catch (NumberFormatException ignored) { /* let parser report */ }\n    return null;\n}\n\n// usage for seconds/minutes: validateStepRange(secondsField, 59); validateStepRange(minutesField, 59);","typeGuard":"public static boolean stepWithinMax(String field, int max) {\n    if (field == null || !field.contains(\"/\")) return true;\n    try {\n        String s = field.substring(field.indexOf('/') + 1).replaceAll(\"[^0-9]\", \"\");\n        return Integer.parseInt(s) <= max;\n    } catch (NumberFormatException e) { return false; }\n}","tryCatchPattern":"try {\n    new CronExpression(expr);\n} catch (ParseException e) {\n    if (e.getMessage().startsWith(\"Increment >= 60\")) {\n        return \"Second/minute steps must be <= 59; move larger intervals to the right field. \" + e.getMessage();\n    }\n    throw e;\n}","preventionTips":["Clamp second/minute steps to 59 in any interval generator.","Distinguish seconds from minutes fields when building 'every N' expressions.","Offer preset intervals (every 15s/30s, every 1/5/10 min) in the UI."],"tags":["cron","xxl-job","step-operator","seconds","minutes","validation","parse-error"],"backgroundTag":null,"analyzedSha":"96fb33f5ec68516da0b0147da06b2eb0419e063a","analyzedAt":"2026-08-14T00:04:16.786Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}