prestodb/presto · error · IllegalArgumentException
Invalid year-month interval:
Error message
Invalid year-month interval:
What it means
IntervalYearMonth.parseMonths parses a year-month interval string (e.g. '1-6') using the FORMAT regex. If the string does not match the '<years>-<months>' shape, this IllegalArgumentException is thrown with the offending value appended to the message.
Source
Thrown at presto-client/src/main/java/com/facebook/presto/client/IntervalYearMonth.java:71
return format("%s%d-%d", sign, months / 12, months % 12);
}
public static int parseMonths(String value)
{
if (value.equals(INT_MIN_VALUE)) {
return Integer.MIN_VALUE;
}
int signum = 1;
if (value.startsWith("-")) {
signum = -1;
value = value.substring(1);
}
Matcher matcher = FORMAT.matcher(value);
if (!matcher.matches()) {
throw new IllegalArgumentException("Invalid year-month interval: " + value);
}
int years = parseInt(matcher.group(1));
int months = parseInt(matcher.group(2));
return toMonths(years, months) * signum;
}
}
View on GitHub (pinned to 55bb57d202)
Solutions
- Check the input matches '<years>-<months>' (optionally signed, e.g. '-1-6').
- Normalize before parsing: convert '18 months' style input to years/months form like '1-6' yourself.
- Wrap parseMonths in try-catch and show the expected format in the error message.
- Route day-time interval strings to IntervalDayTime.parseMillis instead.
Example fix
// before
int months = IntervalYearMonth.parseMonths(userInput); // throws on '1y6m'
// after
Matcher m = Pattern.compile("(-?)(\\d+)-(\\d+)").matcher(userInput.trim());
if (!m.matches()) { throw new IllegalArgumentException("Expected format: years-months, e.g. 1-6"); }
int months = IntervalYearMonth.parseMonths(m.group(1) + m.group(2) + "-" + m.group(3)); Defensive patterns
Strategy: validation
Validate before calling
private static final Pattern INTERVAL_YEAR_MONTH = Pattern.compile("-?\\d+-\\d+");
if (value == null || !INTERVAL_YEAR_MONTH.matcher(value.trim()).matches()) {
throw new IllegalArgumentException("Expected year-month interval like '1-6', got: " + value);
} Try / catch
try { int months = IntervalYearMonth.parseMonths(value); } catch (IllegalArgumentException e) { /* surface expected 'years-months' format */ } Prevention
- Check the '<years>-<months>' shape before calling parseMonths
- Route day-time strings to IntervalDayTime instead
- Normalize textual input ('18 months') into numeric form first
- Centralize interval parsing with pre-validation
When it happens
Trigger: Calling IntervalYearMonth.parseMonths with strings like '18 months', '1y6m', a day-time string such as '1 12:00:00.000', or values with wrong separator (e.g. '1:6' instead of '1-6') that fail the FORMAT regex.
Common situations: Mixing up the two interval types (passing day-time syntax to the year-month parser); constructing intervals from user input without format validation; values taken from logs or other systems with different interval notations.
Related errors
- Invalid day-time interval:
- QualifiedObjectName should have exactly 3 parts, found %s: %
- Bad type signature: '%s'
- Invalid day second interval qualifier: to
- Invalid year month interval qualifier: to
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/a02a2ce38303b9bc.
Report an issue: GitHub.