prestodb/presto · error · IllegalArgumentException

Invalid interval qualifier: to

Error message

Invalid interval qualifier:  to 

What it means

cretePeriodFormatter builds a Joda PeriodFormatter for a DAY–SECOND interval qualifier range. While appending fields in order (HOURS→MINUTES→SECONDS per branch), if the endField does not legally follow the current startField (e.g. endField is not MONTH when starting at MONTH in the year-month variant, or fields out of order), the builder aborts with this IllegalArgumentException.

Source

Thrown at presto-main-base/src/main/java/com/facebook/presto/util/DateTimeUtils.java:593

        List<PeriodParser> parsers = new ArrayList<>();

        PeriodFormatterBuilder builder = new PeriodFormatterBuilder();
        switch (startField) {
            case YEAR:
                builder.appendYears();
                parsers.add(builder.toParser());
                if (endField == IntervalField.YEAR) {
                    break;
                }
                builder.appendLiteral("-");
                // fall through

            case MONTH:
                builder.appendMonths();
                parsers.add(builder.toParser());
                if (endField != IntervalField.MONTH) {
                    throw new IllegalArgumentException("Invalid interval qualifier: " + startField + " to " + endField);
                }
                break;

            case DAY:
                builder.appendDays();
                parsers.add(builder.toParser());
                if (endField == IntervalField.DAY) {
                    break;
                }
                builder.appendLiteral(" ");
                // fall through

            case HOUR:
                builder.appendHours();
                parsers.add(builder.toParser());
                if (endField == IntervalField.HOUR) {
                    break;
                }

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Check the (startField, endField) arguments passed to each INTERVAL_*_FORMATTER static initializer — end must be the same field or the next sub-field in the hierarchy
  2. Fix the enum order or the switch statement so fields are appended in strict order HOUR→MINUTE→SECOND (or YEAR→MONTH)
  3. After fixing, verify DateTimeUtils class loads (any test touching date parsing will exercise the static block)
  4. Add a unit test enumerating all legal qualifier pairs to catch regressions at init time

Example fix

// before
new IntervalFormatter(IntervalField.SECOND, IntervalField.HOUR, ...) // end before start
// after
new IntervalFormatter(IntervalField.HOUR, IntervalField.SECOND, ...)
Defensive patterns

Strategy: try-catch

Validate before calling

// static-init failure: verify class loads early
try { Class.forName("com.facebook.presto.util.DateTimeUtils"); } catch (ExceptionInInitializerError e) { throw new IllegalStateException("DateTimeUtils formatter init failed", e); }

Try / catch

try { INTERVAL_X_FORMATTER = cretePeriodFormatter(start, end); } catch (IllegalArgumentException e) { throw new IllegalStateException("Bad interval qualifier " + start + " to " + end, e); }

Prevention

When it happens

Trigger: Static initialization of the INTERVAL_*_FORMATTER constants with an illegal (startField, endField) pair — e.g. INTERVAL_HOUR_SECOND_FORMATTER built with end earlier than start, or a new formatter constant added with fields in the wrong order. Since it runs in static initializers, it surfaces as ExceptionInInitializerError at class-load time.

Common situations: Developers adding a new interval formatter constant with swapped or non-contiguous fields; refactoring IntervalField enum ordering; backporting patches that change field hierarchy assumptions.

Related errors


AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04). Data as JSON: /api/errors/f962acb6e5d2fb10. Report an issue: GitHub.