jeecgboot/JeecgBoot · error · ParseException

A numeric value between 1 and 5 must follow the '#' option

Error message

A numeric value between 1 and 5 must follow the '#' option

What it means

In the DAY_OF_WEEK branch, after a '#' character the parser reads the rest of the token with Integer.parseInt and requires the nth-week value to be 1-5. Any parse failure (non-numeric) or out-of-range value throws this fixed-text exception. The '#' construct means 'the Nth occurrence of weekday X in a month' (e.g. 0 0 12 ? * 6#3 = third Friday).

Source

Thrown at jeecg-boot/jeecg-server-cloud/jeecg-visual/jeecg-cloud-xxljob/src/main/java/com/xxl/job/admin/business/scheduler/cron/CronExpression.java:590

                    c = s.charAt(i + 3);
                    if (c == '-') {
                        i += 4;
                        sub = s.substring(i, i + 3);
                        eval = getDayOfWeekNumber(sub);
                        if (eval < 0) {
                            throw new ParseException(
                                    "Invalid Day-of-Week value: '" + sub
                                            + "'", i);
                        }
                    } else if (c == '#') {
                        try {
                            i += 4;
                            nthDayOfWeek = Integer.parseInt(s.substring(i));
                            if (nthDayOfWeek < 1 || nthDayOfWeek > 5) {
                                throw new Exception();
                            }
                        } catch (Exception e) {
                            throw new ParseException(
                                    "A numeric value between 1 and 5 must follow the '#' option",
                                    i);
                        }
                    } else if (c == 'L') {
                        lastDayOfWeek = true;
                        i++;
                    }
                }

            } else {
                throw new ParseException(
                        "Illegal characters for this position: '" + sub + "'",
                        i);
            }
            if (eval != -1) {
                incr = 1;
            }
            addToSet(sval, eval, incr, type);

View on GitHub (pinned to 96fb33f5ec)

Solutions

  1. Ensure the value after '#' is an integer strictly between 1 and 5 (1=first, 5=last possible occurrence).
  2. Do not append extra characters after the number - parseInt reads the remainder of the token.
  3. For 'last occurrence' semantics use 'L' (e.g. '6L') instead of '#5'.
  4. Precompute and clamp the nth value when generating the expression programmatically.

Example fix

// before - nth value out of range / blank
String cron = "0 0 12 ? * 6#6";  // 6 > 5 -> error

// after - valid nth (3rd Friday)
String cron = "0 0 12 ? * 6#3";
Defensive patterns

Strategy: validation

Validate before calling

// Validate a '#' nth-weekday token (e.g. 6#3) before assembling the cron string.
public static String validateNthDow(String weekday, int nth) {
    if (weekday == null || !weekday.matches("[1-7]")) return "weekday must be 1-7";
    if (nth < 1 || nth > 5) return "nth occurrence after '#' must be 1-5, got " + nth;
    return null;
}

Type guard

public static boolean isValidNthDow(String token) {
    // matches shapes like 6#3, MON#2
    if (token == null) return false;
    java.util.regex.Pattern p = java.util.regex.Pattern.compile("^(?:[1-7]|SUN|MON|TUE|WED|THU|FRI|SAT)#([1-5])$");
    return p.matcher(token.toUpperCase()).matches();
}

Try / catch

try {
    new CronExpression(expr);
} catch (ParseException e) {
    if (e.getMessage().contains("'#' option")) {
        return "After '#' use an integer 1-5 (1st..5th occurrence). For last weekday use 'L'.";
    }
    throw e;
}

Prevention

When it happens

Trigger: Dow tokens like '6#0', '6#6' (out of 1-5), '6#' (empty -> parseInt throws), 'MON#x' (non-numeric), or '6#3x' (trailing junk after the number is consumed by parseInt of the whole remaining substring). The try block catches Exception broadly so both NumberFormatException and the range check funnel to this message.

Common situations: Wanting 'last weekday of month' and incorrectly using a high nth value; off-by-one confusion (0-based vs 1-based); expression generators that compute nth without clamping; leaving the '#' operand blank.

Related errors


AI-assisted analysis of jeecgboot/JeecgBoot@96fb33f5ec (2026-08-14). Data as JSON: /api/errors/e0b318fb29c70ede. Report an issue: GitHub.