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
- Reference at least one valid member with ${CubeName.memberName} syntax inside the sub query measure's sql.
- Fix the member path typo/namespace so collectMultipliedMeasures can resolve it.
- 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.
- 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
- Always use ${Cube.member} placeholders (never raw SQL) inside subQuery measure sql
- Compile schemas in unit tests before deploy
- Lint schema files for subQuery measures lacking member references
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
- Invalid query format: ${error.message || error.toString()}
- Measure filters aren't allowed in ungrouped query
- Multi stage member '${multiStageMember}' lacks FROM clause i
- Dimension-only measure ${measureName} references cubes (${cu
- '${measures.map(m => m.measure).join(', ')}' reference cubes
AI-assisted analysis of cube-js/cube@7d981676b3 (2026-09-02).
Data as JSON: /api/errors/0f21a34b3c328e01.
Report an issue: GitHub.