{"record":{"id":"b084441651924c42","repo":"flowable/flowable-engine","slug":"can-only-be-specified-for-day-of-month-or-day","errorCode":null,"errorMessage":"'?' can only be specified for Day-of-Month or Day-of-Week.","messagePattern":"'\\?' can only be specified for Day-of-Month or Day-of-Week\\.","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":618,"sourceCode":"                }\n\n            } else {\n                throw new ParseException(\"Illegal characters for this position: '\" + sub + \"'\", i);\n            }\n            if (eval != -1) {\n                incr = 1;\n            }\n            addToSet(sval, eval, incr, type);\n            return (i + 3);\n        }\n\n        if (c == '?') {\n            i++;\n            if ((i + 1) < s.length() && (s.charAt(i) != ' ' && s.charAt(i + 1) != '\\t')) {\n                throw new ParseException(\"Illegal character after '?': \" + s.charAt(i), i);\n            }\n            if (type != DAY_OF_WEEK && type != DAY_OF_MONTH) {\n                throw new ParseException(\"'?' can only be specified for Day-of-Month or Day-of-Week.\", i);\n            }\n            if (type == DAY_OF_WEEK && !lastdayOfMonth) {\n                int val = daysOfMonth.last();\n                if (val == NO_SPEC_INT) {\n                    throw new ParseException(\"'?' can only be specified for Day-of-Month -OR- Day-of-Week.\", 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 == '/' && ((i + 1) >= s.length() || s.charAt(i + 1) == ' ' || s.charAt(i + 1) == '\\t')) {\n                throw new ParseException(\"'/' must be followed by an integer.\", i);","sourceCodeStart":600,"sourceCodeEnd":636,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/calendar/CronExpression.java#L600-L636","documentation":"Thrown when '?' appears in a field other than Day-of-Month or Day-of-Week. In Quartz-style cron, '?' means 'no specific value' and is only legal in the two day fields; the parser enforces this to prevent ambiguity between which day field drives the schedule.","triggerScenarios":"new CronExpression(\"0 ? 12 * * ?\") — '?' in the minutes field; using '?' as a wildcard in seconds, minutes, hours, month, or year fields, often from copying the '?' from the day fields to others.","commonSituations":"Users generalizing 'the ? goes somewhere' after seeing it in day fields; auto-generated UI forms allowing '?' in every field; migration from other schedulers whose dialects permit '?' anywhere.","solutions":["Use '*' instead of '?' in seconds, minutes, hours, month, and year fields.","Reserve '?' for exactly one of Day-of-Month or Day-of-Week (the other should usually be '*' or a concrete value).","Sanitize user input: strip/replace '?' outside the two day fields before parsing.","Show a field-by-field cron builder UI so users never hand-type '?' in the wrong slot."],"exampleFix":"// before\nnew CronExpression(\"0 ? 12 * * ?\");\n// after\nnew CronExpression(\"0 * 12 * * ?\");","handlingStrategy":"validation","validationCode":"// '?' is only legal in fields 4 (day-of-month) and 6 (day-of-week)\nString[] p = expr.trim().split(\"\\\\s+\");\nfor (int i = 0; i < p.length; i++) {\n    if (p[i].contains(\"?\") && i != 3 && i != 5) {\n        throw new IllegalArgumentException(\"'?' not allowed in field \" + (i + 1));\n    }\n}","typeGuard":null,"tryCatchPattern":"try {\n    new CronExpression(expr);\n} catch (java.text.ParseException e) {\n    throw new IllegalArgumentException(\"'?' only valid for Day-of-Month/Day-of-Week in: \" + expr, e);\n}","preventionTips":["Use '*' for 'every' in seconds/minutes/hours/month/year","Reserve '?' for exactly one day field","Offer structured cron builders instead of free-text input"],"tags":["cron","parse-error","wildcard"],"backgroundTag":"invalid-argument-value","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"}