cube-js/cube · error · UserError

Cannot parse selector date range ${selector.dateRange}

Error message

Cannot parse selector date range ${selector.dateRange}

What it means

When queueing pre-aggregation build jobs ('post' action), a `selector.dateRange` (array of exactly two date strings) is parsed via `parseUtcIntoLocalDate`. The API expects dates either in local time without a timezone or as UTC timestamps with a trailing 'Z'. If either endpoint of the range cannot be parsed into a valid date, this UserError is thrown and no jobs are queued.

Source

Thrown at packages/cubejs-api-gateway/src/gateway.ts:1119

  /**
   * Post pre-aggregations build jobs entry point.
   */
  private async preAggregationsJobsPOST(
    context: RequestContext,
    selector: PreAggsSelector,
  ): Promise<string[]> {
    let jobs: string[] = [];

    // There might be a few contexts but dateRange if present is still the same
    // so let's normalize it only once.
    // It's expected that selector.dateRange is provided in local time (without timezone)
    // At the same time it is ok to get timestamps with `Z` (in UTC).
    if (selector.dateRange) {
      const start = parseUtcIntoLocalDate([{ val: selector.dateRange[0] }], 'UTC');
      const end = parseUtcIntoLocalDate([{ val: selector.dateRange[1] }], 'UTC');
      if (!start || !end) {
        throw new UserError(`Cannot parse selector date range ${selector.dateRange}`);
      }
      selector.dateRange = [start, end];
    }

    const promise = Promise.all(
      selector.contexts.map(async (config) => {
        const ctx = <RequestContext>{
          ...context,
          ...config,
        };
        const _jobs = await this.postPreAggregationsBuildJobs(
          ctx,
          selector,
        );
        return _jobs;
      })
    );
    const resolve = await promise;

View on GitHub (pinned to 7d981676b3)

Solutions

  1. Send `dateRange` as a two-element array of strings: `["2024-01-01T00:00:00.000Z", "2024-02-01T00:00:00.000Z"]` (UTC with 'Z') or plain local dates like `["2024-01-01", "2024-02-01"]`.
  2. Convert `Date` objects to ISO UTC strings before sending: `date.toISOString()`.
  3. Ensure the array has exactly two elements in [start, end] order.
  4. Avoid locale-dependent formats ('MM/DD/YYYY') and non-UTC timezone offsets; normalize to ISO 8601 first.
  5. Log the raw `selector.dateRange` you're sending and validate both elements parse with `new Date(v)` and are not NaN before calling the API.

Example fix

// before
{ "action": "post", "selector": { "dateRange": ["01/01/2024", "02/01/2024"] } }

// after
{ "action": "post", "selector": { "dateRange": ["2024-01-01T00:00:00.000Z", "2024-02-01T00:00:00.000Z"] } }
Defensive patterns

Strategy: validation

Validate before calling

function normalizeDateRange(range) {
  if (!Array.isArray(range) || range.length !== 2) throw new Error('dateRange must be [start, end]');
  const [start, end] = range.map(v => {
    const d = v instanceof Date ? v : new Date(v);
    if (isNaN(d.getTime())) throw new Error(`Unparseable date: ${v}`);
    return d.toISOString(); // UTC with Z, accepted by the API
  });
  return [start, end];
}

Type guard

function isParsedDateRange(r: unknown): r is [string, string] {
  return Array.isArray(r) && r.length === 2 &&
    r.every(v => typeof v === 'string' && !isNaN(Date.parse(v)));
}

Try / catch

try {
  const jobs = await postPreAggJobs({ action: 'post', selector: { ...selector, dateRange: normalizeDateRange(selector.dateRange) } });
} catch (e) {
  if (String(e.message).includes('Cannot parse selector date range')) {
    console.error('Bad dateRange:', selector.dateRange); // convert to ISO-8601 UTC
  }
}

Prevention

When it happens

Trigger: POST to `/cubejs-system/v1/pre-aggregations/jobs` with `action: 'post'` and `selector.dateRange` containing unparseable values: an empty string, `null`/`undefined` entries, non-ISO formats like '01/02/2024' or 'Feb 3 2024' if the parser rejects them, an array with fewer/more than the two accessed positions (`dateRange[0]`, `dateRange[1]`), or ISO strings with offsets like '+02:00' that the parser doesn't accept.

Common situations: Passing JavaScript `Date` objects serialized incorrectly (e.g., '[object Object]' or epoch numbers as strings); locale-formatted dates from a UI datepicker; time-zone-offset ISO strings ('2024-01-01T00:00:00+02:00') instead of 'Z'-suffixed UTC; accidentally passing a single date string instead of a two-element array.

Related errors


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