cube-js/cube · error · UserError

Nothing to join in rollup join. Target joins ${JSON.stringif

Error message

Nothing to join in rollup join. Target joins ${JSON.stringify(targetJoins)} are included in existing rollup joins ${JSON.stringify(existingJoins)}

What it means

During rollup-join construction, Cube computes which target joins still need new pre-aggregations by subtracting joins already covered by existing rollup pre-aggregations. If the difference is empty, there is nothing new to join — every target join duplicates an existing one — which usually indicates a misconfigured rollupJoin, so it throws.

Source

Thrown at packages/cubejs-schema-compiler/src/adapter/PreAggregations.ts:1071

        }

        const targetJoins = this.resolveJoinMembers(builtJoinTree);

        // TODO join hints?
        const existingJoins = preAggObjsToJoin
          .map(p => this.resolveJoinMembers(
            this.query.joinTreeForHints(this.cubesHintsFromPreAggregation(p), true)
          ))
          .flat();

        const nonExistingJoins = targetJoins.filter(target => !existingJoins.find(
          existing => existing.originalFrom === target.originalFrom &&
            existing.originalTo === target.originalTo &&
            R.equals(existing.fromMembers, target.fromMembers) &&
            R.equals(existing.toMembers, target.toMembers)
        ));
        if (!nonExistingJoins.length) {
          throw new UserError(`Nothing to join in rollup join. Target joins ${JSON.stringify(targetJoins)} are included in existing rollup joins ${JSON.stringify(existingJoins)}`);
        }
        return nonExistingJoins.map(join => {
          const fromPreAggObj = this.preAggObjForJoin(preAggObjsToJoin, join.fromMembers, join, `${preAggObj.cube}.${preAggObj.preAggregationName}`);
          const toPreAggObj = this.preAggObjForJoin(preAggObjsToJoin, join.toMembers, join, `${preAggObj.cube}.${preAggObj.preAggregationName}`);
          return {
            ...join,
            fromPreAggObj,
            toPreAggObj
          };
        });
      }
    );
  }

  private preAggObjForJoin(
    preAggObjsToJoin: PreAggregationForQuery[],
    joinMembers: string[],
    join: JoinEdgeWithMembers,

View on GitHub (pinned to 7d981676b3)

Solutions

  1. Remove the redundant rollupJoin and query the existing (full) pre-aggregation directly.
  2. Add at least one new cube/membership to the rollupJoin so there is a genuinely new join to materialize.
  3. Deduplicate pre-aggregation lists across rollupJoin definitions.
  4. Refactor to a single pre-aggregation that spans all required cubes if joins are already covered.

Example fix

// before
rollupJoin: { preAggregations: [ordersMain, usersMain] } // duplicates joins already in ordersUsersFull rollup
// after
// query 'ordersUsersFull' pre-aggregation directly, or extend rollupJoin with a third cube (e.g. productsMain)
Defensive patterns

Strategy: validation

Validate before calling

// dedupe pre-aggregations across rollupJoins before submitting schema
const seen = new Set();
for (const rj of rollupJoins) {
  const key = [...rj.preAggregations].sort().join('+');
  if (seen.has(key)) throw new Error(`Redundant rollupJoin covering same joins twice: ${key}`);
  seen.add(key);
}

Try / catch

try { await cubeApi.load(query); } catch (e) { if (/Nothing to join in rollup join/.test(e.message)) {
  // the rollupJoin is redundant; query the existing full pre-aggregation instead
  return queryViaExistingRollup(); } throw e; }

Prevention

When it happens

Trigger: A rollupJoin whose participating pre-aggregations already cover all joins in the built join tree: every target join's originalFrom/originalTo and member sets match an existing rollup join's, leaving nonExistingJoins empty.

Common situations: Listing the same join's pre-aggs in two rollupJoins; a rollupJoin that duplicates what a single pre-aggregation already provides; copy-pasting rollupJoin definitions after the underlying single-cube pre-aggregation was already replaced by a full rollup.

Related errors


AI-assisted analysis of cube-js/cube@7d981676b3 (2026-09-02). Data as JSON: /api/errors/26711c0e2bb4df2a. Report an issue: GitHub.