cube-js/cube · error · UserError
'${preAggregation.cube}.${preAggregation.preAggregationName}
Error message
'${preAggregation.cube}.${preAggregation.preAggregationName}' referenced by '${cube}.${preAggregationName}' rollupLambda doesn't have partition granularity. Partition granularity is required if multiple rollups are provided. What it means
When a rollupLambda references multiple rollups, every referenced pre-aggregation must define partitionGranularity, since concatenation of partitions requires each source rollup to be partitioned. This static check throws if any referenced pre-aggregation lacks it.
Source
Thrown at packages/cubejs-schema-compiler/src/adapter/PreAggregations.ts:1255
});
referencedPreAggregations.forEach(preAgg => {
references.rollupsReferences.push(preAgg.references);
});
const lambdaResult = canUsePreAggregation(references);
return {
...preAggObj,
canUsePreAggregation: lambdaResult.canUse,
leafMeasureMatch: lambdaResult.leafMeasureMatch,
referencedPreAggregations,
};
} else {
return preAggObj;
}
}
public static checkPartitionGranularityDefined(cube: string, preAggregationName: string, preAggregation: PreAggregationForQuery): string {
if (!preAggregation.preAggregation.partitionGranularity) {
throw new UserError(`'${preAggregation.cube}.${preAggregation.preAggregationName}' referenced by '${cube}.${preAggregationName}' rollupLambda doesn't have partition granularity. Partition granularity is required if multiple rollups are provided.`);
}
return preAggregation.preAggregation.partitionGranularity;
}
public static memberNameMismatchValidation(preAggA: PreAggregationForQuery, preAggB: PreAggregationForQuery, memberType: 'measures' | 'dimensions' | 'timeDimensions') {
const preAggAMemberNames = PreAggregations.memberShortNames(preAggA.references[memberType]);
const preAggBMemberNames = PreAggregations.memberShortNames(preAggB.references[memberType]);
if (!R.equals(
preAggAMemberNames,
preAggBMemberNames
)) {
throw new UserError(`Names for ${memberType} doesn't match between '${preAggA.cube}.${preAggA.preAggregationName}' and '${preAggB.cube}.${preAggB.preAggregationName}': ${JSON.stringify(preAggAMemberNames)} does not equal to ${JSON.stringify(preAggBMemberNames)}`);
}
}
private static memberShortNames(memberArray: (string | PreAggregationTimeDimensionReference)[]): string[] {
return memberArray.map(member => {
if (typeof member !== 'string') {View on GitHub (pinned to 7d981676b3)
Solutions
- Add partitionGranularity: 'month' (or day/week/year) to every pre-aggregation referenced by a multi-rollup rollupLambda.
- If a rollup should not be partitioned, remove it from the multi-rollup lambda or give it its own lambda.
- Audit all rollups listed in rollups arrays for the partitionGranularity key.
Example fix
// before
ordersByMonth: { measures: [CUBE.count], timeDimension: Orders.createdAt, granularity: 'month' }
// after
ordersByMonth: { measures: [CUBE.count], timeDimension: Orders.createdAt, granularity: 'month', partitionGranularity: 'month' } Defensive patterns
Strategy: validation
Validate before calling
// Require partitionGranularity on every rollup referenced by a multi-rollup rollupLambda
function requirePartitionGranularity(def, preAggDefs) {
if (def.type === 'rollupLambda' && (def.rollups || []).length > 1) {
for (const r of def.rollups) {
if (!preAggDefs[r]?.partitionGranularity) throw new Error(`${r} needs partitionGranularity for multi-rollup rollupLambda`);
}
}
} Type guard
function isPartitioned(p) { return typeof p?.partitionGranularity === 'string' && p.partitionGranularity.length > 0; } Try / catch
try { await cube.query(query); } catch (e) { if (/doesn't have partition granularity/.test(e.message)) { console.error('Add partitionGranularity to the referenced rollup:', e.message); } else throw e; } Prevention
- Make partitionGranularity mandatory for any pre-aggregation used in lambdas
- Audit legacy pre-aggregations after adding them to a rollups array
- Enforce the attribute via a shared pre-aggregation factory function
- Test-compile all lambdas in CI
When it happens
Trigger: checkPartitionGranularityDefined is called during rollupLambda building with 2+ referenced rollups, and one of them (or one defined via a reference without partitionGranularity) has no partitionGranularity set in its definition.
Common situations: Adding a second rollup to an existing lambda while the first/second rollup was never partitioned; pre-aggregations defined before partitionGranularity existed (older schemas); referencing a shared pre-aggregation that other queries use unpartitioned.
Related errors
- '${prevReferencedPreAggregation.cube}.${prevReferencedPreAgg
- rollupLambda '${cube}.${preAggregationName}' should referenc
- unionWithSourceData can be enabled only for pre-aggregation
- Names for ${memberType} doesn't match between '${preAggA.cub
- Unable to detect column types for pre-aggregation on empty v
AI-assisted analysis of cube-js/cube@7d981676b3 (2026-09-02).
Data as JSON: /api/errors/77de74e4c048938c.
Report an issue: GitHub.