{"record":{"id":"0f21a34b3c328e01","repo":"cube-js/cube","slug":"subquery-measure-m-expressionname-should-refere","errorCode":null,"errorMessage":"Subquery measure ${m.expressionName} should reference at least one member","messagePattern":"Subquery measure (.+?) should reference at least one member","errorType":"validation","errorClass":"UserError","httpStatus":null,"severity":"error","filePath":"packages/cubejs-schema-compiler/src/adapter/BaseQuery.js","lineNumber":2261,"sourceCode":"    return [measureName, [{\n      multiplied,\n      measure: attachedMeasure,\n    }]];\n  }\n\n  collectRootMeasureToHierarchy(context) {\n    const notAddedMeasureFilters = R.flatten(this.measureFilters.map(f => f.getMembers()))\n      .filter(f => R.none(m => m.measure === f.measure, this.measures));\n\n    return R.fromPairs(this.measures.concat(notAddedMeasureFilters).map(m => {\n      const collectedMeasures = this.collectFrom(\n        [m],\n        this.collectMultipliedMeasures(context),\n        context ? ['collectMultipliedMeasures', JSON.stringify(context)] : 'collectMultipliedMeasures',\n        this.queryCache\n      );\n      if (m.expressionName && !collectedMeasures.length && !m.isMemberExpression) {\n        throw new UserError(`Subquery measure ${m.expressionName} should reference at least one member`);\n      }\n\n      if (collectedMeasures.length === 0 && m.isMemberExpression) {\n        // `m` is member expression measure, but does not reference any other measure\n        // Consider this dimensions-only measure. This can happen at least in 2 cases:\n        // 1. Ad-hoc aggregation over dimension: SELECT MAX(dim) FROM cube\n        // 2. Ungrouped query with SQL pushdown will render every column as measure: SELECT dim1 FROM cube WHERE LOWER(dim2) = 'foo';\n        // Measures like this needs a special treatment to attach them to cube and decide if they are multiplied or not\n        // This would return measure object in `measure`, not path\n        // TODO return measure object for every measure\n        return this.dimensionOnlyMeasureToHierarchy(context, m);\n      }\n\n      let measureKey;\n      if (typeof m.measure === 'string') {\n        measureKey = m.measure;\n      } else if (m.isMemberExpression) {\n        // TODO expressionName vs definition?","sourceCodeStart":2243,"sourceCodeEnd":2279,"githubUrl":"https://github.com/cube-js/cube/blob/7d981676b36392fec34088b9afab6bdcad40207c/packages/cubejs-schema-compiler/src/adapter/BaseQuery.js#L2243-L2279","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before (no member referenced)\nmeasures: {\n  userCount: { type: 'number', sql: 'SELECT count(*) FROM users', subQuery: true }\n}\n// after\nmeasures: {\n  userCount: {\n    type: 'count',\n    sql: 'SELECT count(*) FROM ${Users.sql} WHERE ${Users.id} = ${user_id}',\n    subQuery: true\n  }\n}","handlingStrategy":"validation","validationCode":"function assertSubQueryReferencesMembers(measure) {\n  if (measure.subQuery && !/\\$\\{\\s*[A-Za-z_]\\w*\\.\\w+\\s*\\}/.test(measure.sql || '')) {\n    throw new Error(`Subquery measure must reference a member via \\${Cube.member} in sql`);\n  }\n}","typeGuard":"const isValidSubQueryMeasure = (m) => !(m.expressionName && !m.isMemberExpression) || /\\$\\{[^}]+\\}/.test(m.sql || '');","tryCatchPattern":"try {\n  compiler.compile();\n} catch (e) {\n  if (/should reference at least one member/.test(e.message)) {\n    console.error('Add a ${Cube.member} reference inside the sub query measure sql');\n  }\n  throw e;\n}","preventionTips":["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"],"tags":["sub-query","measures","schema-validation"],"backgroundTag":"subquery-measure-no-member-reference","analyzedSha":"7d981676b36392fec34088b9afab6bdcad40207c","analyzedAt":"2026-09-02T03:45:10.400Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}