alibaba/spring-cloud-alibaba · error · ParseException

'L' option is not valid here. (pos={})

Error message

'L' option is not valid here. (pos={})

What it means

Thrown in checkNext when 'L' follows a value but the current field is not DAY_OF_WEEK (guard at CronExpression.java:530-531). 'L' (last) is only valid in day-of-month (standalone) or day-of-week (as <n>L); here the '<n>L' form was used in some other field like minutes or hours.

Source

Thrown at spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-schedulerx/src/main/java/com/alibaba/cloud/scheduling/schedulerx/util/CronExpression.java:531

		int end = -1;
		int i = pos;

		if (i >= s.length()) {
			addToSet(val, end, -1, type);
			return i;
		}

		char c = s.charAt(pos);

		if (c == 'L') {
			if (type == DAY_OF_WEEK) {
				if (val < 1 || val > 7) {
					throw new ParseException("Day-of-Week values must be between 1 and 7", -1);
				}
				lastdayOfWeek = true;
			}
			else {
				throw new ParseException("'L' option is not valid here. (pos=" + i + ")", i);
			}
			final TreeSet<Integer> set = getSet(type);
			set.add(val);
			i++;
			return i;
		}

		if (c == 'W') {
			if (type == DAY_OF_MONTH) {
				nearestWeekday = true;
			}
			else {
				throw new ParseException("'W' option is not valid here. (pos=" + i + ")", i);
			}
			if (val > 31) {
				throw new ParseException("The 'W' option does not make sense with values larger than 31 (max number of days in a month)", i);
			}
			final TreeSet<Integer> set = getSet(type);

View on GitHub (pinned to 115d590110)

Solutions

  1. Use 'L' only in day-of-month (e.g. '0 0 0 L * ?') or as '<n>L' in day-of-week.
  2. Remove 'L' from seconds/minutes/hours/month fields.
  3. Recheck the six-field ordering.

Example fix

// before
new CronExpression("0 0L * * * ?");
// after
new CronExpression("0 0 0 L * ?"); // last day of month at 00:00
Defensive patterns

Strategy: validation

Validate before calling

// 'L' may appear in day-of-month (standalone) or day-of-week (as <n>L) only.
static boolean lUsedInValidField(String[] fields) {
    // fields: seconds minutes hours dom month dow
    if (fields.length < 6) return false;
    if (fields[1].contains("L") || fields[2].contains("L") || fields[4].contains("L")) return false;
    if (fields[0].contains("L")) return false;
    return true;
}

Try / catch

try {
    CronExpression cron = new CronExpression(raw);
} catch (ParseException e) {
    throw new IllegalArgumentException("Invalid cron expression: " + raw, e);
}

Prevention

When it happens

Trigger: `new CronExpression("0 0L * * * ?")` ('L' after 0 in minutes), or `0 0 5L * * ?` ('L' after 5 in hours). Any '<n>L' in seconds, minutes, hours, or month.

Common situations: Developer mistakenly appends 'L' to a time field thinking it means 'last', or a field-count error moves a weekday expression into the hours/minutes position.

Related errors


AI-assisted analysis of alibaba/spring-cloud-alibaba@115d590110 (2026-08-14). Data as JSON: /api/errors/8d7a638e3ca58f56. Report an issue: GitHub.