{"record":{"id":"9c0bd16f479a7c69","repo":"cube-js/cube","slug":"dimension-only-measure-measurename-references-c","errorCode":null,"errorMessage":"Dimension-only measure ${measureName} references cubes (${cubeNamesForMeasure}) that lead to row multiplication. Please rewrite it using sub query.","messagePattern":"Dimension-only measure (.+?) references cubes \\((.+?)\\) that lead to row multiplication\\. Please rewrite it using sub query\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/cubejs-schema-compiler/src/adapter/BaseQuery.js","lineNumber":2224,"sourceCode":"    )(\n      memberNamesForMeasure\n    );\n\n    let cubeNameToAttach;\n    switch (cubeNamesForMeasure.length) {\n      case 0:\n        // For zero reference measure there's nothing to derive info about measure from\n        // So it assume that it's a regular measure, and it will be evaluated on top of join tree\n        return [measureName, [{\n          multiplied: false,\n          measure: m.measure,\n        }]];\n      case 1:\n        [cubeNameToAttach] = cubeNamesForMeasure;\n        break;\n      default: {\n        if (cubeNamesForMeasure.some(cubeName => this.multipliedJoinRowResult(cubeName))) {\n          throw new Error(`Dimension-only measure ${measureName} references cubes (${cubeNamesForMeasure}) that lead to row multiplication. Please rewrite it using sub query.`);\n        }\n        // Dimensions from several cubes, but none of them is on the multiplied\n        // side of a join - safe to evaluate the expression on top of join tree\n        return [measureName, [{\n          multiplied: false,\n          measure: m.measure,\n        }]];\n      }\n    }\n\n    const multiplied = this.multipliedJoinRowResult(cubeNameToAttach) || false;\n\n    const attachedMeasure = {\n      ...m.measure,\n      originalCubeName: m.measure.cubeName,\n      cubeName: cubeNameToAttach\n    };\n","sourceCodeStart":2206,"sourceCodeEnd":2242,"githubUrl":"https://github.com/cube-js/cube/blob/7d981676b36392fec34088b9afab6bdcad40207c/packages/cubejs-schema-compiler/src/adapter/BaseQuery.js#L2206-L2242","documentation":"A 'dimension-only measure' (a measure expression referencing only dimensions) that touches cubes on the multiplied side of a join would double-count rows. Cube throws this Error when more than one cube is involved and at least one of them leads to row multiplication (multiplied join factor).","triggerScenarios":"Creating an ad-hoc measure whose expression aggregates only dimensions (e.g. MAX(dim) or a calculated dimension expression) where the referenced cubes include one on the many-side of a join (multipliedJoinRowResult(cubeName) is true) and the measure spans multiple cubes (default case in cubeNameToAttach switch).","commonSituations":"Schema authors writing calculated measures over dimensions from a joined many-side table; ad-hoc aggregations like SELECT MAX(dim) that cross cubes in fan-out joins.","solutions":["Rewrite the measure as a sub query (subQuery: true with a defined subQuery measure) so aggregation happens before the join.","Restrict the measure's expression to a single cube (attach to one cube) so the multiplied-cube check is bypassed.","Adjust the join so the referenced cube is not on the multiplied side (e.g. use a belongs-to instead of has-many join direction).","Pre-aggregate the dimension expression in the underlying cube's sql or a rollup."],"exampleFix":"// before (dimension-only measure spanning multiplied cubes)\nmeasures: {\n  maxEmail: { type: 'max', sql: '${Users.email}' }\n}\n// after (rewrite as sub query)\nmeasures: {\n  maxEmail: {\n    type: 'number',\n    sql: \"SELECT max(email) FROM users WHERE ${filter}\",\n    subQuery: true\n  }\n}","handlingStrategy":"validation","validationCode":"// Prefer subQuery measures when aggregating dimensions from a many-side cube\nfunction dimensionOnlyMeasureIsSafe(measureRefs, multipliedCubes) {\n  return !measureRefs.some(c => multipliedCubes.includes(c));\n}","typeGuard":null,"tryCatchPattern":"try {\n  return await cubeApi.load(query);\n} catch (e) {\n  if (/Dimension-only measure .* row multiplication/.test(e.message)) {\n    console.error(`Rewrite ${e.message.match(/Dimension-only measure (\\S+)/)?.[1]} as a subQuery measure`);\n  }\n  throw e;\n}","preventionTips":["Never build measures over dimensions that cross has-many joins","Use subQuery: true for cross-cube dimension aggregations","Model fan-out aggregations in the schema, not ad-hoc queries"],"tags":["fanout","join-multiplication","measures"],"backgroundTag":"row-multiplication-fanout","analyzedSha":"7d981676b36392fec34088b9afab6bdcad40207c","analyzedAt":"2026-09-02T03:45:10.400Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}