{"record":{"id":"e9c64c062e22ebc5","repo":"flowable/flowable-engine","slug":"unexpected-character-c-after","errorCode":null,"errorMessage":"Unexpected character '<c>' after '/'","messagePattern":"Unexpected character '<c>' after '/'","errorType":"validation","errorClass":"java.text.ParseException","httpStatus":null,"severity":"error","filePath":"modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/calendar/CronExpression.java","lineNumber":852,"sourceCode":"            i++;\n            c = s.charAt(i);\n            int v2 = Integer.parseInt(String.valueOf(c));\n            i++;\n            if (i >= s.length()) {\n                checkIncrementRange(v2, type, i);\n                addToSet(val, end, v2, type);\n                return i;\n            }\n            c = s.charAt(i);\n            if (c >= '0' && c <= '9') {\n                ValueSet vs = getValue(v2, s, i);\n                int v3 = vs.value;\n                checkIncrementRange(v3, type, i);\n                addToSet(val, end, v3, type);\n                i = vs.pos;\n                return i;\n            } else {\n                throw new ParseException(\"Unexpected character '\" + c + \"' after '/'\", i);\n            }\n        }\n\n        addToSet(val, end, 0, type);\n        i++;\n        return i;\n    }\n\n    public String getCronExpression() {\n        return cronExpression;\n    }\n\n    public String getExpressionSummary() {\n        StringBuilder buf = new StringBuilder();\n\n        buf.append(\"seconds: \");\n        buf.append(getExpressionSetSummary(seconds));\n        buf.append(\"\\n\");","sourceCodeStart":834,"sourceCodeEnd":870,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/calendar/CronExpression.java#L834-L870","documentation":"After a '/' increment operator, the parser expects either a plain integer step, a 'N/step' range form, or a name/range it can resolve (e.g. 'MON/2', 'JAN/3'). The character encountered after consuming the '/' prefix did not fit any accepted form, so this ParseException is thrown indicating the unexpected character that followed '/'.","triggerScenarios":"new CronExpression(expr) with forms like '*/X' where X is not numeric or a valid name, '0/#', '0/L' or '0/?' — i.e. '/' followed by a character that cannot start a step value or valid name token in that field.","commonSituations":"Combining special characters incorrectly (assuming '/' composes with 'L', 'W', '#' or '?'); typos like '0/.5'; locale-dependent decimal separators in dynamically generated steps ('0/1,5' from European number formatting); misunderstanding which special chars are legal after '/' in the Quartz dialect.","solutions":["Use a plain integer step after '/', e.g. '*/10' or '0/10' — 'L', '#', '?' and similar specials cannot follow '/'","If a fractional or computed step is needed, round it to an integer before building the string and beware locale number formatting (use Locale.ROOT when formatting)","If you meant 'last day' semantics, put 'L' in the day-of-month field directly (e.g. '0 0 0 L * ?'), not after a slash","Pre-validate with CronExpression.isValidExpression(expr) to catch malformed expressions early"],"exampleFix":"// before\nString cron = \"0 0 0 */L * ?\"; // invalid '*/L'\n// after\nString cron = \"0 0 0 L * ?\"; // last day of month","handlingStrategy":"validation","validationCode":"String expr = \"0 0 0 */10 * ?\";\nif (!CronExpression.isValidExpression(expr)) {\n    throw new IllegalArgumentException(\"Invalid cron expression: \" + expr);\n}\n// guard step rendering\nif (!stepPart.matches(\"\\\\d+\")) {\n    throw new IllegalArgumentException(\"Only integer steps allowed after '/': \" + stepPart);\n}","typeGuard":"boolean isValidStepAfterSlash(String stepPart) {\n    return stepPart != null && stepPart.matches(\"\\\\d+\");\n}","tryCatchPattern":"try {\n    CronExpression cron = new CronExpression(expr);\n} catch (ParseException e) {\n    log.error(\"Unexpected character after '/' in cron {}: {}\", expr, e.getMessage());\n    throw new ConfigurationException(\"Invalid cron increment: \" + expr, e);\n}","preventionTips":["Only integers (or resolvable names/ranges) may follow '/'; never 'L', '#', '?', 'W' or decimals","Format numeric steps with Locale.ROOT to avoid decimal commas","If 'last day' semantics are needed, use 'L' directly in the day-of-month field, not after '/'","Pre-validate all expressions with CronExpression.isValidExpression"],"tags":["cron","scheduling","parsing","validation"],"backgroundTag":"invalid-regex-pattern","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}