cube-js/cube · error
Pre-aggregation '${this.preAggregation.tableName}' requested
Error message
Pre-aggregation '${this.preAggregation.tableName}' requested to build ${partitionRanges.length} partitions which exceeds the maximum number of partitions per pre-aggregation of ${this.options.maxPartitions} What it means
For partitioned pre-aggregations, Cube splits the requested date range into partition ranges to build. partitionRanges throws if the number of partitions to build exceeds options.maxPartitions, protecting the instance from an accidental explosion of build jobs (memory, queue, storage).
Source
Thrown at packages/cubejs-query-orchestrator/src/orchestrator/PreAggregationPartitionRangeLoader.ts:449
);
if (!dateRange) {
// If there's no date range intersection between query data range and pre-aggregation build range
// use last partition so outer query can receive expected table structure.
dateRange = [buildRange[1], buildRange[1]];
}
const partitionRanges = this.compilerCacheFn(
['timeSeries', this.preAggregation.partitionGranularity, JSON.stringify(dateRange), `${this.preAggregation.timestampPrecision}`],
() => PreAggregationPartitionRangeLoader.timeSeries(
this.preAggregation.partitionGranularity,
dateRange,
this.preAggregation.timestampPrecision
)
);
if (partitionRanges.length > this.options.maxPartitions) {
throw new Error(
`Pre-aggregation '${this.preAggregation.tableName}' requested to build ${partitionRanges.length} partitions which exceeds the maximum number of partitions per pre-aggregation of ${this.options.maxPartitions}`
);
}
return { buildRange: dateRange, partitionRanges };
}
public async loadBuildRange(timestampFormat: string = DEFAULT_TS_FORMAT): Promise<QueryDateRange> {
const { preAggregationStartEndQueries } = this.preAggregation;
const [startDate, endDate] = await Promise.all(
preAggregationStartEndQueries.map(
async rangeQuery => PreAggregationPartitionRangeLoader.extractDate(await this.loadRangeQuery(rangeQuery), this.preAggregation.timezone, timestampFormat),
),
);
if (!this.preAggregation.partitionGranularity) {
return this.orNowIfEmpty([startDate, endDate]);
}View on GitHub (pinned to 7d981676b3)
Solutions
- Increase maxPartitions in preAggregations options if the large number of partitions is intentional.
- Narrow the query's date range (add timeDimension dateRange filters) so fewer partitions are needed.
- Use coarser partition granularity (month instead of day) for long histories.
- Configure partitionRangeAnchor / rolling windows to limit how many partitions a single build materializes.
- Ensure queries always include bounded date ranges (validation rules) before hitting the loader.
Example fix
// before
preAggregationsOptions: { maxPartitions: 100 }
// after
preAggregationsOptions: { maxPartitions: 1000 } // or narrow query dateRange Defensive patterns
Strategy: validation
Validate before calling
function countPartitions(start, end, granularity) {
const ms = { day: 86400000, hour: 3600000, month: 2629800000 }[granularity];
return Math.ceil((new Date(end) - new Date(start)) / ms) + 1;
}
if (countPartitions(range[0], range[1], granularity) > maxPartitions) throw new Error('Date range exceeds maxPartitions'); Try / catch
try {
return await loader.loadPreAggregations();
} catch (e) {
if (String(e.message).includes('exceeds the maximum number of partitions')) {
// narrow date range or raise maxPartitions in preAggregations options
}
throw e;
} Prevention
- Always bound time dimension date ranges in application queries.
- Choose partition granularity appropriate to data span (month for years of data).
- Size maxPartitions to your longest legitimate query range plus headroom.
- Validate ranges at the API gateway before they reach the orchestrator.
When it happens
Trigger: Querying/building a partitioned pre-aggregation whose dateRange spans more partitions than maxPartitions (e.g., 6 years of day partitions when maxPartitions is 100); a very fine granularity (day/hour) with a wide unbounded range; missing filters so Cube plans to build the full partition extent.
Common situations: Date range filters omitted or unexpectedly wide in dashboard queries; day-granularity partitions over long histories; freshly changed partition granularity without adjusting maxPartitions; errors in date parsing producing huge ranges.
Related errors
- No pre-aggregation partitions were built yet for the pre-agg
- Date range expected to be an array with 2 elements but ${ran
- Unable to detect column types for pre-aggregation on empty v
- Create table failed: ${e}
- Unsupported table data passed to ${this.constructor}
AI-assisted analysis of cube-js/cube@7d981676b3 (2026-09-02).
Data as JSON: /api/errors/25ef6266f98b4cf5.
Report an issue: GitHub.