{"record":{"id":"150dfb659ac5eb3b","repo":"alibaba/spring-cloud-alibaba","slug":"illegal-character-after","errorCode":null,"errorMessage":"Illegal character after '?': {}","messagePattern":"Illegal character after '\\?': (.+?)","errorType":"exception","errorClass":"ParseException","httpStatus":null,"severity":"error","filePath":"spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-schedulerx/src/main/java/com/alibaba/cloud/scheduling/schedulerx/util/CronExpression.java","lineNumber":388,"sourceCode":"\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\tthrow new ParseException(\n\t\t\t\t\t\t\"Illegal characters for this position: '\" + sub + \"'\",\n\t\t\t\t\t\ti);\n\t\t\t}\n\t\t\tif (eval != -1) {\n\t\t\t\tincr = 1;\n\t\t\t}\n\t\t\taddToSet(sval, eval, incr, type);\n\t\t\treturn (i + 3);\n\t\t}\n\n\t\tif (c == '?') {\n\t\t\ti++;\n\t\t\tif ((i + 1) < s.length()\n\t\t\t\t\t&& (s.charAt(i) != ' ' && s.charAt(i + 1) != '\\t')) {\n\t\t\t\tthrow new ParseException(\"Illegal character after '?': \"\n\t\t\t\t\t\t+ s.charAt(i), i);\n\t\t\t}\n\t\t\tif (type != DAY_OF_WEEK && type != DAY_OF_MONTH) {\n\t\t\t\tthrow new ParseException(\n\t\t\t\t\t\t\"'?' can only be specfied for Day-of-Month or Day-of-Week.\",\n\t\t\t\t\t\ti);\n\t\t\t}\n\t\t\tif (type == DAY_OF_WEEK && !lastdayOfMonth) {\n\t\t\t\tfinal int val = daysOfMonth.last();\n\t\t\t\tif (val == NO_SPEC_INT) {\n\t\t\t\t\tthrow new ParseException(\n\t\t\t\t\t\t\t\"'?' can only be specfied for Day-of-Month -OR- Day-of-Week.\",\n\t\t\t\t\t\t\ti);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\taddToSet(NO_SPEC_INT, -1, 0, type);\n\t\t\treturn i;","sourceCodeStart":370,"sourceCodeEnd":406,"githubUrl":"https://github.com/alibaba/spring-cloud-alibaba/blob/115d5901102009492e05d5ec18c3f79cad4077d0/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-schedulerx/src/main/java/com/alibaba/cloud/scheduling/schedulerx/util/CronExpression.java#L370-L406","documentation":"Thrown while parsing a '?' token: after consuming the '?' the parser checks the immediately following character; if it is not a space or tab (and more characters remain), it throws ParseException 'Illegal character after '?': <char>'. The '?' must stand alone as the entire field value.","triggerScenarios":"A field like '?X' or '?,5' where '?' is followed by other characters, e.g. '0 0 0 ?5 * *'. The check at CronExpression.java:383-387 fires when (i+1 < length) and the char at i is not space and the next is not tab.","commonSituations":"Typing '?*' or '?5' thinking '?' can combine with other values; a stray character appended to '?'; copy-paste artefacts.","solutions":["Make '?' the entire content of its field (no trailing characters).","If you meant 'any value', use '*' instead of '?'; '?' specifically means 'no specific value' and is only for day-of-month/day-of-week.","Validate at config load."],"exampleFix":"# before\n0 0 0 ?5 * *\n\n# after\n0 0 0 ? * *","handlingStrategy":"try-catch","validationCode":"static String validateCron(String cron) throws ParseException {\n    new com.alibaba.cloud.scheduling.schedulerx.util.CronExpression(cron);\n    return cron;\n}","typeGuard":"// '?' must be a standalone field\nstatic boolean qMarksAreStandalone(String[] f) {\n    for (String tok : f) {\n        if (tok.contains(\"?\") && !tok.equals(\"?\")) return false;\n    }\n    return true;\n}","tryCatchPattern":"try {\n    new CronExpression(cron);\n} catch (ParseException e) {\n    // \"Illegal character after '?': 5\"\n    log.error(\"'?' must stand alone in cron '{}'\", cron);\n}","preventionTips":["Use '?' only as a complete field, never combined with other characters.","Prefer '*' over '?' unless you specifically need the day-field mutual-exclusion semantics."],"tags":["java","schedulerx","cron","parsing","validation"],"backgroundTag":null,"analyzedSha":"115d5901102009492e05d5ec18c3f79cad4077d0","analyzedAt":"2026-08-14T04:47:13.900Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}