{"record":{"id":"e8fb4e4d043c51ab","repo":"jeecgboot/JeecgBoot","slug":"must-be-followed-by-an-integer","errorCode":null,"errorMessage":"'/' must be followed by an integer.","messagePattern":"'/' must be followed by an integer\\.","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":643,"sourceCode":"                if (!daysOfMonth.isEmpty() && daysOfMonth.last() == NO_SPEC_INT) {\n                    throw new ParseException(\n                            \"'?' can only be specified for Day-of-Month -OR- Day-of-Week.\",\n                            i);\n                }\n            }\n\n            addToSet(NO_SPEC_INT, -1, 0, type);\n            return i;\n        }\n\n        if (c == '*' || c == '/') {\n            if (c == '*' && (i + 1) >= s.length()) {\n                addToSet(ALL_SPEC_INT, -1, incr, type);\n                return i + 1;\n            } else if (c == '/'\n                    && ((i + 1) >= s.length() || s.charAt(i + 1) == ' ' || s\n                    .charAt(i + 1) == '\\t')) {\n                throw new ParseException(\"'/' must be followed by an integer.\", i);\n            } else if (c == '*') {\n                i++;\n            }\n            c = s.charAt(i);\n            if (c == '/') { // is an increment specified?\n                i++;\n                if (i >= s.length()) {\n                    throw new ParseException(\"Unexpected end of string.\", i);\n                }\n\n                incr = getNumericValue(s, i);\n\n                i++;\n                if (incr > 10) {\n                    i++;\n                }\n                checkIncrementRange(incr, type, i);\n            } else {","sourceCodeStart":625,"sourceCodeEnd":661,"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#L625-L661","documentation":"When the current char is '/', the parser checks whether the next char exists and is not whitespace. If '/' is at the end of the string or immediately followed by a space/tab, there is no increment value, so this is thrown. The '/' step operator must always be followed by an integer (e.g. '0/15' = every 15 starting at 0).","triggerScenarios":"Trailing '/' with no operand: '0 0 0/ * * ?', '0 0 0 0/ * * ?' where the '/' is the last meaningful char, or '*/ ' with a space after the slash. Also '0 0 0 5/ * * ?' (space after slash).","commonSituations":"Truncated pasted expression where the step value was cut off; typo leaving the slash dangling; building a step expression with an empty increment variable.","solutions":["Always follow '/' with a positive integer: '0/15', '*/5', '10-30/2'.","If you only wanted 'every value', drop the slash entirely and use '*'.","When generating 'start/step' strings, never emit the slash unless the step is non-empty."],"exampleFix":"// before - dangling '/' with no increment\nString cron = \"0 0 0/ * * ?\";  // '/' must be followed by an integer\n\n// after - supply an increment (every 2 hours)\nString cron = \"0 0 0/2 * * ?\";","handlingStrategy":"validation","validationCode":"// Every '/' in a field must be followed by a non-whitespace integer.\npublic static String validateStepOperator(String field) {\n    if (field == null) return null;\n    int slash = field.indexOf('/');\n    if (slash < 0) return null;\n    if (slash == field.length() - 1) return \"'/' at end of field with no increment\";\n    String rest = field.substring(slash + 1);\n    if (rest.isEmpty() || rest.startsWith(\" \") || rest.startsWith(\"\\t\")) {\n        return \"'/' must be followed by an integer: \" + field;\n    }\n    return null;\n}","typeGuard":"public static boolean stepHasIntegerOperand(String field) {\n    if (field == null || !field.contains(\"/\")) return true;\n    int slash = field.indexOf('/');\n    return slash < field.length() - 1\n        && field.substring(slash + 1).matches(\"[0-9]+.*\");\n}","tryCatchPattern":"try {\n    new CronExpression(expr);\n} catch (ParseException e) {\n    if (e.getMessage().startsWith(\"'/' must be followed\")) {\n        return \"Add an integer after each '/'. \" + e.getMessage();\n    }\n    throw e;\n}","preventionTips":["Never emit a '/' unless a positive integer follows it.","In a step builder, append '/step' only when step is non-empty and > 0.","Trim and re-check each field's '/' operand before submitting the cron string."],"tags":["cron","xxl-job","step-operator","validation","parse-error"],"backgroundTag":null,"analyzedSha":"96fb33f5ec68516da0b0147da06b2eb0419e063a","analyzedAt":"2026-08-14T00:04:16.786Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}