cube-js/cube · error · UserError
No rollups found that can be used for a rollup join from "${
Error message
No rollups found that can be used for a rollup join from "${join.from}" (fromMembers: ${JSON.stringify(join.fromMembers)}) to "${join.to}" (toMembers: ${JSON.stringify(join.toMembers)}). Check the "${rollupJoinPreAggName}" pre-aggregation definition — you may have forgotten to specify the full dimension paths What it means
For each join in a rollupJoin, Cube must find exactly one rollup pre-aggregation that contains all the dimension members of that join's side (fromMembers/toMembers). If no candidate pre-aggregation references every required member, this UserError fires and points at the rollupJoin definition — typically because abbreviated dimension paths were used instead of full Cube.dimension paths.
Source
Thrown at packages/cubejs-schema-compiler/src/adapter/PreAggregations.ts:1099
});
}
);
}
private preAggObjForJoin(
preAggObjsToJoin: PreAggregationForQuery[],
joinMembers: string[],
join: JoinEdgeWithMembers,
rollupJoinPreAggName: string,
): PreAggregationForQuery {
const fromPreAggObj = preAggObjsToJoin
.filter(p => joinMembers.every(m => !!p.references.dimensions.find(d => m === d)));
if (!fromPreAggObj.length) {
const msg = `No rollups found that can be used for a rollup join from "${
join.from}" (fromMembers: ${JSON.stringify(join.fromMembers)}) to "${join.to}" (toMembers: ${
JSON.stringify(join.toMembers)}). Check the "${
rollupJoinPreAggName}" pre-aggregation definition — you may have forgotten to specify the full dimension paths`;
throw new UserError(msg);
}
if (fromPreAggObj.length > 1) {
throw new UserError(
`Multiple rollups found that can be used for rollup join ${JSON.stringify(join)}: ${fromPreAggObj.map(p => this.preAggregationId(p)).join(', ')}`,
);
}
return fromPreAggObj[0];
}
private resolveJoinMembers(join: FinishedJoinTree): JoinEdgeWithMembers[] {
const joinMap = new Set<string>();
return join.joins.map(j => {
joinMap.add(j.originalFrom);
const memberPaths = this.query.collectMemberNamesFor(() => this.query.evaluateSql(j.originalFrom, j.join.sql)).map(m => m.split('.'));
const invalidMembers = memberPaths.filter(m => !joinMap.has(m[0]) && m[0] !== j.originalTo);View on GitHub (pinned to 7d981676b3)
Solutions
- Use fully qualified member paths everywhere (e.g. Users.country, not 'country') in rollupJoin from/to and pre-aggregation dimensions.
- Ensure each side's pre-aggregation includes the join key dimensions in its references.dimensions.
- Check for renamed dimensions/members and update the rollupJoin definition accordingly.
- Verify exactly one matching rollup exists per join side — zero triggers this error, more than one throws the 'Multiple rollups found' companion error.
Example fix
// before
rollupJoin: [{ from: 'Users', to: 'Orders', fromMembers: ['country'], toMembers: ['userCountry'] }]
// after
rollupJoin: [{ from: 'Users', to: 'Orders', fromMembers: ['Users.country'], toMembers: ['Orders.userCountry'] }] Defensive patterns
Strategy: validation
Validate before calling
// verify each rollupJoin member appears in the referenced pre-aggregation's dimensions
const isFullPath = (m) => /^[A-Za-z_]\w*\.[A-Za-z_]\w*$/.test(m);
for (const j of rollupJoin) {
[...j.fromMembers, ...j.toMembers].forEach(m => {
if (!isFullPath(m)) throw new Error(`rollupJoin member '${m}' must be a full path like Users.country`);
});
} Type guard
const isFullyQualifiedMember = (m: string): m is `${string}.${string}` => /^[A-Za-z_]\w*\.[A-Za-z_]\w*$/.test(m); Try / catch
try { await cubeApi.load(query); } catch (e) { if (/No rollups found that can be used for a rollup join/.test(e.message)) {
const preAggName = e.message.match(/Check the "([^"]+)"/)?.[1];
throw new Error(`Add full dimension paths to pre-aggregation '${preAggName}'`); } throw e; } Prevention
- Always use fully qualified member paths in rollupJoin from/to
- Include join-key dimensions in each participating pre-aggregation
- Update rollupJoin definitions when renaming dimensions
- Compile all rollupJoins in a schema test before deploying
When it happens
Trigger: A rollupJoin references pre-aggregations whose references.dimensions do not include all members of join.fromMembers or join.toMembers — e.g. members written as 'country' or 'Users.country' instead of the fully qualified path in the join definition or the pre-agg dimensions.
Common situations: Copy-pasted rollupJoin examples with partial member paths; pre-aggregation defined on a subset of dimensions not covering the join keys; renaming dimensions without updating rollupJoin member references.
Related errors
- Can't build join tree for pre-aggregation ${preAggObj.cube}.
- Nothing to join in rollup join. Target joins ${JSON.stringif
- Multiple rollups found that can be used for rollup join ${JS
- Members ${invalidMembers.join(', ')} in join from '${j.origi
- From members are not found in [${memberPaths.map(m => m.join
AI-assisted analysis of cube-js/cube@7d981676b3 (2026-09-02).
Data as JSON: /api/errors/b684154bf49fd864.
Report an issue: GitHub.