{"record":{"id":"04c24d66c940ebff","repo":"flowable/flowable-engine","slug":"can-only-be-specified-for-day-of-month-or-da","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":623,"sourceCode":"            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);\n            } else if (c == '*') {\n                i++;\n            }\n            c = s.charAt(i);\n            if (c == '/') { // is an increment specified?","sourceCodeStart":605,"sourceCodeEnd":641,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/calendar/CronExpression.java#L605-L641","documentation":"Thrown when '?' appears in Day-of-Week while Day-of-Month was also set to '?' (daysOfMonth.last() == NO_SPEC_INT). Quartz requires exactly one of the two day fields to have a specific value; if both are '?', the schedule is ambiguous and rejected. Note the parser also requires Day-of-Week '?' only when lastdayOfMonth is false ('L' in DOM).","triggerScenarios":"new CronExpression(\"0 0 12 ? * ?\") — both day fields are '?'; programmatic builders that default both day fields to '?' without checking the other.","commonSituations":"Form UIs where both day selectors default to 'any (?)' and the user never touches either; serialization round-trips that lose which field was intentionally specified; template expressions with two placeholders both filled with '?'.","solutions":["Set one day field to '?': e.g. '0 0 12 ? * MON' or '0 0 12 15 * ?', never both.","In expression builders, enforce that exactly one of day-of-month/day-of-week is '?' and the other is '*' or a concrete value.","If you want 'every day', use '?' in one field and '*' in the other: '0 0 12 * * ?'.","Pre-validate stored cron strings on startup and reject ambiguous ones with a clear message."],"exampleFix":"// before\nnew CronExpression(\"0 0 12 ? * ?\");\n// after\nnew CronExpression(\"0 0 12 * * ?\");","handlingStrategy":"validation","validationCode":"String[] p = expr.trim().split(\"\\\\s+\");\nif (p.length >= 6 && p[3].equals(\"?\") && p[5].equals(\"?\")) {\n    throw new IllegalArgumentException(\"Day-of-Month and Day-of-Week cannot both be '?': \" + expr);\n}","typeGuard":null,"tryCatchPattern":"try {\n    new CronExpression(expr);\n} catch (java.text.ParseException e) {\n    if (e.getMessage().contains(\"-OR-\")) {\n        throw new IllegalArgumentException(\"Set '?' in only one of Day-of-Month / Day-of-Week: \" + expr, e);\n    }\n}","preventionTips":["Exactly one day field may be '?'; the other must be '*' or a value","Default builder UIs should preset one day field to '*'","Reject ambiguous schedules at save time, not at trigger time"],"tags":["cron","parse-error","ambiguous-fields"],"backgroundTag":"conflicting-config-options","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"}