cube-js/cube · error · UserError
Time series queries without dateRange aren't supported
Error message
Time series queries without dateRange aren't supported
What it means
BaseTimeDimension.timeSeries() generates the array of date intervals for a time-series query, which requires an explicit dateRange to compute start/end. Called by values() and seriesSql(), it throws this UserError when the query has no dateRange — without it the series would be unbounded.
Source
Thrown at packages/cubejs-schema-compiler/src/adapter/BaseTimeDimension.ts:268
// that the interval and the granularity offset are stacked/fits with date range
if (this.dateRange && (this.granularityObj.isPredefined() ||
!this.granularityObj.isAlignedWithDateRange([this.dateFromFormatted(), this.dateToFormatted()]))) {
return this.query.minGranularity(this.granularityObj.minGranularity(), this.dateRangeGranularity());
}
// We return the granularity as-is, including custom ones,
// because baseQuery.granularityHierarchies correctly expands all custom granularities into hierarchies.
return this.granularityObj.granularity;
}
);
}
return this.rollupGranularityValue;
}
public timeSeries() {
if (!this.dateRange) {
throw new UserError('Time series queries without dateRange aren\'t supported');
}
if (!this.granularityObj) {
return [[this.dateFromFormatted(), this.dateToFormatted()]];
}
return this.granularityObj.timeSeriesForInterval([this.dateFromFormatted(), this.dateToFormatted()], { timestampPrecision: this.query.timestampPrecision() });
}
public resolvedGranularity() {
return this.granularityObj ? this.granularityObj.resolvedGranularity() : null;
}
public resolvedGranularityAsIs() {
return this.granularityObj ? this.granularityObj.granularity : null;
}
public wildcardRange() {View on GitHub (pinned to 7d981676b3)
Solutions
- Add a dateRange to the timeDimension of the query, e.g. dateRange: ['2024-01-01', '2024-03-31']
- If an open-ended query is intended, compute a concrete dateRange client-side before sending
- For rolling windows, use dateRange expressions like 'last month' that resolve to a bounded range
Example fix
// before
timeDimensions: [{ dimension: 'Orders.createdAt', granularity: 'day' }]
// after
timeDimensions: [{ dimension: 'Orders.createdAt', granularity: 'day', dateRange: ['2024-01-01', '2024-01-31'] }] Defensive patterns
Strategy: validation
Validate before calling
function validateTimeDimensions(query) {
for (const td of query.timeDimensions || [])
if (td.granularity && !td.dateRange) throw new Error('Time-series queries require a dateRange');
} Type guard
const hasBoundedDateRange = (td) => Array.isArray(td?.dateRange) && td.dateRange.length === 2 && td.dateRange.every(Boolean);
Try / catch
try { const res = await cubeApi.load(q); } catch (e) { if (/Time series queries without dateRange/.test(e.message)) { q.timeDimensions.forEach(td => td.dateRange ||= defaultRange()); return cubeApi.load(q); } throw e; } Prevention
- Always attach a dateRange to timeDimensions that specify a granularity
- Use relative ranges ('last week') so the range stays bounded
- Validate queries client-side before sending them to the API
When it happens
Trigger: Issuing a time-series query (e.g. granularity with series generation, used by charting/rolling window flows) where timeDimensions entry lacks a dateRange — e.g. { dimension: 'Orders.createdAt', granularity: 'day' } with no dateRange, or dateRange: null.
Common situations: BI client requesting a series without a date filter; passing only dateRangeMapped or forgetting dateRange when constructing queries programmatically; using seriesSql-dependent features on unbounded queries.
Related errors
- The count of generated date ranges (${count}) for the reques
- Unsupported time granularity: ${granularity}
- options.timestampPrecision is required, actual: ${options.ti
- Can't parse date: '${from}'
- Can't parse date: '${to}'
AI-assisted analysis of cube-js/cube@7d981676b3 (2026-09-02).
Data as JSON: /api/errors/c2e51440373af177.
Report an issue: GitHub.