{"record":{"id":"04d3469dfbcbd1db","repo":"jeecgboot/JeecgBoot","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":"jeecg-boot/jeecg-server-cloud/jeecg-visual/jeecg-cloud-xxljob/src/main/java/com/xxl/job/admin/business/scheduler/cron/CronExpression.java","lineNumber":620,"sourceCode":"                        \"Illegal characters for this position: '\" + sub + \"'\",\n                        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()\n                    && (s.charAt(i) != ' ' && s.charAt(i + 1) != '\\t')) {\n                throw new ParseException(\"Illegal character after '?': \"\n                        + s.charAt(i), i);\n            }\n            if (type != DAY_OF_WEEK && type != DAY_OF_MONTH) {\n                throw new ParseException(\n                        \"'?' can only be specified for Day-of-Month or Day-of-Week.\",\n                        i);\n            }\n            if (type == DAY_OF_WEEK) {\n                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);","sourceCodeStart":602,"sourceCodeEnd":638,"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#L602-L638","documentation":"'?' (NO_SPEC) is semantically allowed only in the day-of-month or day-of-week fields, because those two fields are mutually exclusive in Quartz. If the parser encounters '?' while parsing SECOND, MINUTE, HOUR, or MONTH (type != DAY_OF_WEEK and != DAY_OF_MONTH), it throws this. It enforces the Quartz rule that you specify '?' in one day field to let the other be set.","triggerScenarios":"A '?' in a non-day field: '0 ? 0 * * *' (MINUTE='?'), '? * * * * *' (SECOND), '0 0 0 * ? *' is fine but '0 0 0 * 1 ? *' with MONTH or '0 ? 0 * * ?' is not. Common when a developer copies the dom/dow '?' pattern into every field.","commonSituations":"Misunderstanding '?' as a generic wildcard; putting '?' in seconds/minutes to mean 'every'; templates that fill unused fields with '?'.","solutions":["Use '*' (not '?') for 'every value' in SECOND/MINUTE/HOUR/MONTH.","Reserve '?' exclusively for the dom-or-dow field you are leaving unspecified.","Validate that '?' appears only in field positions 4 (dom) or 6 (dow) of the expression."],"exampleFix":"// before - '?' in the minute field\nString cron = \"0 ? 0 * * ?\";  // Illegal: ? in MINUTE\n\n// after - '*' for every minute, '?' only in a day field\nString cron = \"0 * 0 * * ?\";","handlingStrategy":"validation","validationCode":"// '?' is only legal in dom (index 3) or dow (index 5) of the 6-field array.\npublic static String validateQuestionMarkPlacement(String expr) {\n    String[] f = expr.trim().split(\"\\\\s+\");\n    for (int i = 0; i < f.length && i < 6; i++) {\n        if (f[i].contains(\"?\") && i != 3 && i != 5) {\n            return \"'?' is only allowed in day-of-month or day-of-week, found in field \" + (i + 1);\n        }\n    }\n    return null;\n}","typeGuard":"public static boolean isQuestionMarkInValidField(String[] fields) {\n    for (int i = 0; i < fields.length && i < 6; i++) {\n        if (fields[i].contains(\"?\") && i != 3 && i != 5) return false;\n    }\n    return true;\n}","tryCatchPattern":"try {\n    new CronExpression(expr);\n} catch (ParseException e) {\n    if (e.getMessage().contains(\"Day-of-Month or Day-of-Week\")) {\n        return \"Use '*' (not '?') in second/minute/hour/month; reserve '?' for the day fields. \" + e.getMessage();\n    }\n    throw e;\n}","preventionTips":["Only allow '?' in the dom or dow field positions; reject it elsewhere.","Educate users that '*' means 'every', '?' means 'unspecified' for day fields only.","Default non-day fields to '*' in any cron builder template."],"tags":["cron","xxl-job","wildcard","field-validation","parse-error"],"backgroundTag":null,"analyzedSha":"96fb33f5ec68516da0b0147da06b2eb0419e063a","analyzedAt":"2026-08-14T00:04:16.786Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}