cube-js/cube · error · UserError

Subquery measure ${m.expressionName} should reference at lea

Error message

Subquery measure ${m.expressionName} should reference at least one member

What it means

Sub query measures (measures whose value comes from another query) must reference at least one member of the outer query so Cube can correlate them. When a sub query measure's expressionName resolves to an empty collected-measures set and it is not a member expression, Cube throws this UserError.

Source

Thrown at packages/cubejs-schema-compiler/src/adapter/BaseQuery.js:2261

    return [measureName, [{
      multiplied,
      measure: attachedMeasure,
    }]];
  }

  collectRootMeasureToHierarchy(context) {
    const notAddedMeasureFilters = R.flatten(this.measureFilters.map(f => f.getMembers()))
      .filter(f => R.none(m => m.measure === f.measure, this.measures));

    return R.fromPairs(this.measures.concat(notAddedMeasureFilters).map(m => {
      const collectedMeasures = this.collectFrom(
        [m],
        this.collectMultipliedMeasures(context),
        context ? ['collectMultipliedMeasures', JSON.stringify(context)] : 'collectMultipliedMeasures',
        this.queryCache
      );
      if (m.expressionName && !collectedMeasures.length && !m.isMemberExpression) {
        throw new UserError(`Subquery measure ${m.expressionName} should reference at least one member`);
      }

      if (collectedMeasures.length === 0 && m.isMemberExpression) {
        // `m` is member expression measure, but does not reference any other measure
        // Consider this dimensions-only measure. This can happen at least in 2 cases:
        // 1. Ad-hoc aggregation over dimension: SELECT MAX(dim) FROM cube
        // 2. Ungrouped query with SQL pushdown will render every column as measure: SELECT dim1 FROM cube WHERE LOWER(dim2) = 'foo';
        // Measures like this needs a special treatment to attach them to cube and decide if they are multiplied or not
        // This would return measure object in `measure`, not path
        // TODO return measure object for every measure
        return this.dimensionOnlyMeasureToHierarchy(context, m);
      }

      let measureKey;
      if (typeof m.measure === 'string') {
        measureKey = m.measure;
      } else if (m.isMemberExpression) {
        // TODO expressionName vs definition?

View on GitHub (pinned to 7d981676b3)

Solutions

  1. Reference at least one valid member with ${CubeName.memberName} syntax inside the sub query measure's sql.
  2. Fix the member path typo/namespace so collectMultipliedMeasures can resolve it.
  3. If truly no measure is needed, convert it to a member-expression measure (isMemberExpression path) or a plain calculated measure instead of a sub query.
  4. Validate the schema locally (schema compiler tests) before deploying.

Example fix

// before (no member referenced)
measures: {
  userCount: { type: 'number', sql: 'SELECT count(*) FROM users', subQuery: true }
}
// after
measures: {
  userCount: {
    type: 'count',
    sql: 'SELECT count(*) FROM ${Users.sql} WHERE ${Users.id} = ${user_id}',
    subQuery: true
  }
}
Defensive patterns

Strategy: validation

Validate before calling

function assertSubQueryReferencesMembers(measure) {
  if (measure.subQuery && !/\$\{\s*[A-Za-z_]\w*\.\w+\s*\}/.test(measure.sql || '')) {
    throw new Error(`Subquery measure must reference a member via \${Cube.member} in sql`);
  }
}

Type guard

const isValidSubQueryMeasure = (m) => !(m.expressionName && !m.isMemberExpression) || /\$\{[^}]+\}/.test(m.sql || '');

Try / catch

try {
  compiler.compile();
} catch (e) {
  if (/should reference at least one member/.test(e.message)) {
    console.error('Add a ${Cube.member} reference inside the sub query measure sql');
  }
  throw e;
}

Prevention

When it happens

Trigger: Defining a measure with subQuery / subQuery options whose sql or referenced expression does not pull in any measure/dimension member — collectMultipliedMeasures returns [] while expressionName is set and isMemberExpression is false.

Common situations: Typo in the referenced member inside a sub query sql (so nothing resolves), using raw SQL columns instead of ${...} member references, or copying a subQuery measure template and emptying its member references.

Related errors


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