jeecgboot/JeecgBoot · error · ParseException

Invalid Month value: '{sub}'

Error message

Invalid Month value: '{sub}'

What it means

Raised in storeExpressionVals when the MONTH field token starts with an uppercase letter (A-Z) but the 3-character substring is not a recognized month abbreviation. getMonthNumber(sub) returns -1, so sval = -1+1 = 0, which is <= 0. The parser only accepts the three-letter abbreviations JAN..DEC in this alphabetic branch; anything else (a typo, a 2-letter code, a non-English abbreviation) fails here.

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:552

    }

    protected int storeExpressionVals(int pos, String s, int type)
            throws ParseException {

        int incr = 0;
        int i = skipWhiteSpace(pos, s);
        if (i >= s.length()) {
            return i;
        }
        char c = s.charAt(i);
        if ((c >= 'A') && (c <= 'Z') && (!s.equals("L")) && (!s.equals("LW")) && (!s.matches("^L-[0-9]*[W]?"))) {
            String sub = s.substring(i, i + 3);
            int sval = -1;
            int eval = -1;
            if (type == MONTH) {
                sval = getMonthNumber(sub) + 1;
                if (sval <= 0) {
                    throw new ParseException("Invalid Month value: '" + sub + "'", i);
                }
                if (s.length() > i + 3) {
                    c = s.charAt(i + 3);
                    if (c == '-') {
                        i += 4;
                        sub = s.substring(i, i + 3);
                        eval = getMonthNumber(sub) + 1;
                        if (eval <= 0) {
                            throw new ParseException("Invalid Month value: '" + sub + "'", i);
                        }
                    }
                }
            } else if (type == DAY_OF_WEEK) {
                sval = getDayOfWeekNumber(sub);
                if (sval < 0) {
                    throw new ParseException("Invalid Day-of-Week value: '"
                            + sub + "'", i);
                }

View on GitHub (pinned to 96fb33f5ec)

Solutions

  1. Replace the offending token with a valid 3-letter abbreviation from JAN,FEB,MAR,APR,MAY,JUN,JUL,AUG,SEP,OCT,NOV,DEC.
  2. If you prefer numbers, use 1-12 instead of names (1=January).
  3. Check the substring length: the parser reads exactly s.substring(i, i+3), so a 1-2 letter alpha token will produce an invalid slice.
  4. When building ranges like JAN-MAR, ensure both endpoints are valid 3-letter codes.

Example fix

// before - misspelled month abbreviation
String cron = "0 0 0 ? JNE ?";  // 'JNE' invalid -> Invalid Month value: 'JNE'

// after - correct abbreviation (or numeric)
String cron = "0 0 0 ? JUN ?";
// or
String cron = "0 0 0 ? 6 ?";
Defensive patterns

Strategy: validation

Validate before calling

private static final java.util.Set<String> MONTHS = java.util.Set.of(
    "JAN","FEB","MAR","APR","MAY","JUN","JUL","AUG","SEP","OCT","NOV","DEC");

// Validate the MONTH field token (single, list, or range) before parsing.
public static String validateMonthField(String field) {
    for (String part : field.split(",")) {
        for (String end : part.split("-")) {
            String t = end.trim().toUpperCase();
            if (t.equals("*") || t.equals("?") || t.matches("\\d+(/\\d+)?")) continue;
            if (!MONTHS.contains(t)) return "invalid month token: " + end;
        }
    }
    return null;
}

Type guard

public static boolean isValidMonthToken(String token) {
    String t = token == null ? "" : token.trim().toUpperCase();
    return "*".equals(t) || "?".equals(t)
        || t.matches("\\d+(/\\d+)?")
        || MONTHS.contains(t);
}

Try / catch

try {
    new CronExpression(expr);
} catch (ParseException e) {
    if (e.getMessage().startsWith("Invalid Month value")) {
        // surface a hint about valid 3-letter codes
        errors.rejectValue("monthField", "cron.month.invalid",
            "Use JAN..DEC (3 letters) or 1..12. Got: " + e.getMessage());
    } else throw e;
}

Prevention

When it happens

Trigger: Cron strings whose month field is an unrecognized alpha token, e.g. '0 0 0 ? JUN,FEB *' is fine but '0 0 0 ? JNE *' (typo), '0 0 0 ? JU *' (truncated), or '0 0 0 ? June *' (full name) trigger it. Also fires when an alpha token in the month position is actually a stray letter from a malformed range like 'JAN-DEC' where the dash parser takes a 3-char slice that is not a month.

Common situations: Typing month names from memory and misspelling an abbreviation; using full month names (the parser wants 3 letters only); locale confusion where a developer assumes localized month names are accepted; truncation when an expression is programmatically built by substring and the last token is short.

Related errors


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