cube-js/cube · error · UserError

Names for ${memberType} doesn't match between '${preAggA.cub

Error message

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)}

What it means

All rollups concatenated by a rollupLambda must expose identical member sets. memberNameMismatchValidation compares the short member names of measures (or dimensions/timeDimensions) between two referenced pre-aggregations with R.equals (order-sensitive); any mismatch throws this UserError listing both name arrays.

Source

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

      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') {
        return `${member.dimension.split('.')[1]}.${member.granularity}`;
      } else {
        return member.split('.').at(-1)!;
      }
    });
  }

  public rollupMatchResultDescriptions() {
    return this.rollupMatchResults().map(p => ({
      name: this.query.cubeEvaluator.pathFromArray([p.cube, p.preAggregationName]),
      tableName: this.preAggregationTableName(p.cube, p.preAggregationName, p.preAggregation),
      references: p.references,

View on GitHub (pinned to 7d981676b3)

Solutions

  1. Make the measures/dimensions/timeDimensions lists identical (same members, same order) across all rollups referenced by the lambda.
  2. Update the stale rollup that lacks the newly added member.
  3. Check the JSON arrays in the error to identify which member is extra/missing/reordered and fix that definition.

Example fix

// before
ordersA: { measures: [CUBE.count], dimensions: [Orders.status] }
ordersB: { measures: [CUBE.count], dimensions: [Orders.status, Orders.country] } // extra dimension
// after
ordersA: { measures: [CUBE.count], dimensions: [Orders.status, Orders.country] }
ordersB: { measures: [CUBE.count], dimensions: [Orders.status, Orders.country] }
Defensive patterns

Strategy: validation

Validate before calling

// Ensure identical member sets (names and order) across a lambda's rollups
function unionCompatible(preAggs) {
  const key = p => JSON.stringify([p.measures, p.dimensions, p.timeDimensions]);
  const first = key(preAggs[0]);
  if (!preAggs.every(p => key(p) === first)) throw new Error('Rollups in rollupLambda must have identical measures/dimensions/timeDimensions');
}

Type guard

function sameMembers(a, b) { return JSON.stringify(a.references.measures) === JSON.stringify(b.references.measures) && JSON.stringify(a.references.dimensions) === JSON.stringify(b.references.dimensions) && JSON.stringify(a.references.timeDimensions) === JSON.stringify(b.references.timeDimensions); }

Try / catch

try { await cube.query(query); } catch (e) { if (/Names for .* doesn't match between/.test(e.message)) { console.error('Align member lists across lambda rollups per the diff in message:', e.message); } else throw e; }

Prevention

When it happens

Trigger: During rollupLambda construction, consecutive referenced pre-aggregations have different sets/order of measures, dimensions, or timeDimensions in their references — e.g. one rollup includes an extra dimension or lists members in a different order.

Common situations: Adding a new dimension to one rollup in a lambda but not the others; members defined in different order across cubes; one rollup using a different time dimension path; a schema drift where one referenced pre-aggregation was updated alone.

Related errors


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