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
- 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"]`.
- Convert `Date` objects to ISO UTC strings before sending: `date.toISOString()`.
- Ensure the array has exactly two elements in [start, end] order.
- Avoid locale-dependent formats ('MM/DD/YYYY') and non-UTC timezone offsets; normalize to ISO 8601 first.
- 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
- Always send ISO 8601 strings (toISOString()) or plain 'YYYY-MM-DD' local dates — never Date objects, epochs, or locale formats.
- Normalize all dates through a single helper before any API call.
- Ensure the range has exactly two elements in [start, end] order.
- Avoid timezone offsets like '+02:00'; use 'Z'-suffixed UTC.
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
- Can't parse date: '${from}'
- Can't parse date: '${to}'
- Can't parse date: '${dateString}'
- Invalid Job query format: ${error.message || error.toString(
- No job description provided
AI-assisted analysis of cube-js/cube@7d981676b3 (2026-09-02).
Data as JSON: /api/errors/90b4f1b76afc2980.
Report an issue: GitHub.