cube-js/cube · error

Complex intervals like "${interval}" are not supported. Plea

Error message

Complex intervals like "${interval}" are not supported. Please use Year to Month or Day to second intervals

What it means

Redshift cannot apply date_bin with intervals that mix month-family units (year/month/quarter) and time-family units (week/day/hour/minute/second), since such intervals have no fixed length. dateBin throws this error when parseSqlInterval yields parts from both families.

Source

Thrown at packages/cubejs-schema-compiler/src/adapter/RedshiftQuery.ts:55

    let result = date;

    for (const [datePart, intervalValue] of Object.entries(intervalParsed)) {
      result = `DATEADD(${datePart}, ${intervalValue}, ${result})`;
    }

    return result;
  }

  /**
   * Redshift doesn't support Interval values with month or year parts (as Postgres does)
   * so we need to make date math on our own.
   */
  public override dateBin(interval: string, source: string, origin: string): string {
    const intervalParsed = parseSqlInterval(interval);

    if ((intervalParsed.year || intervalParsed.month || intervalParsed.quarter) &&
        (intervalParsed.week || intervalParsed.day || intervalParsed.hour || intervalParsed.minute || intervalParsed.second)) {
      throw new Error(`Complex intervals like "${interval}" are not supported. Please use Year to Month or Day to second intervals`);
    }

    if (intervalParsed.year || intervalParsed.month || intervalParsed.quarter) {
      let totalMonths = 0;

      if (intervalParsed.year) {
        totalMonths += intervalParsed.year * 12;
      }

      if (intervalParsed.quarter) {
        totalMonths += intervalParsed.quarter * 3;
      }

      if (intervalParsed.month) {
        totalMonths += intervalParsed.month;
      }

      return `DATEADD(

View on GitHub (pinned to 7d981676b3)

Solutions

  1. Use an interval from a single family: either Y/M/Q only (e.g. '3 months') or W/D/H/MIN/S only (e.g. '2 days 3 hours' is still mixed-unit day-to-second, so prefer one unit like '1 day' if it still throws — day-to-second combos without month parts are allowed per the message)
  2. Convert month-family intervals to an approximate day count only if your data semantics allow it
  3. Define separate granularities/pre-aggregations per unit instead of one compound interval

Example fix

// before
const interval = '1 year 6 months';
query.dateBin(interval, src, origin);
// after
const interval = '18 months'; // single month-family interval
Defensive patterns

Strategy: validation

Validate before calling

const p = parseSqlInterval(interval);
const hasMonthFamily = !!(p.year || p.month || p.quarter);
const hasTimeFamily = !!(p.week || p.day || p.hour || p.minute || p.second);
if (hasMonthFamily && hasTimeFamily) throw new Error('Redshift: split month-family and day-to-second intervals');

Try / catch

try { return query.dateBin(interval, src, origin); } catch (e) { if (e.message.includes('Complex intervals')) { /* substitute single-family interval */ } throw e; }

Prevention

When it happens

Trigger: Calling dateBin with a compound interval like '1 month 2 days', '1 year 3 hours', or '2 quarter 5 minute' on a RedshiftQuery instance (directly or via dateBin-based granularity).

Common situations: Reusing a Postgres-style granularity interval in a Redshift pre-aggregation; copy-pasting interval strings like '1 year 6 months' from other dialects; generated granularities that combine units.

Related errors


AI-assisted analysis of cube-js/cube@7d981676b3 (2026-09-02). Data as JSON: /api/errors/676a85e5e5ea98fc. Report an issue: GitHub.