{"record":{"id":"39fe6ef7dd1644e9","repo":"cube-js/cube","slug":"rolluplambda-cube-preaggregationname-shoul","errorCode":null,"errorMessage":"rollupLambda '${cube}.${preAggregationName}' should reference at least one rollup","messagePattern":"rollupLambda '(.+?)\\.(.+?)' should reference at least one rollup","errorType":"validation","errorClass":"UserError","httpStatus":null,"severity":"error","filePath":"packages/cubejs-schema-compiler/src/adapter/PreAggregations.ts","lineNumber":1209,"sourceCode":"        leafMeasureMatch: joinResult.leafMeasureMatch,\n        preAggregationsToJoin,\n        rollupJoin,\n      };\n    } else if (preAggregation.type === 'rollupLambda') {\n      // TODO evaluation optimizations. Should be cached or moved to compile time.\n      const referencedPreAggregations = preAggObj.references.rollups.map(\n        name => {\n          const [referencedCube, referencedPreAggregation] = this.query.cubeEvaluator.parsePath('preAggregations', name);\n          return this.evaluatedPreAggregationObj(\n            referencedCube,\n            referencedPreAggregation,\n            this.query.cubeEvaluator.byPath('preAggregations', name) as PreAggregationDefinitionExtended,\n            canUsePreAggregation\n          );\n        }\n      );\n      if (referencedPreAggregations.length === 0) {\n        throw new UserError(`rollupLambda '${cube}.${preAggregationName}' should reference at least one rollup`);\n      }\n      referencedPreAggregations.forEach((referencedPreAggregation, i) => {\n        if (i === referencedPreAggregations.length - 1 && preAggObj.preAggregation.unionWithSourceData && preAggObj.cube !== referencedPreAggregations[i].cube) {\n          throw new UserError(`unionWithSourceData can be enabled only for pre-aggregation within '${preAggObj.cube}' cube but '${referencedPreAggregations[i].preAggregationName}' pre-aggregation is defined within '${referencedPreAggregations[i].cube}' cube`);\n        }\n        referencedPreAggregations[i] = {\n          ...referencedPreAggregations[i],\n          preAggregation: {\n            ...referencedPreAggregations[i].preAggregation,\n            unionWithSourceData: i === referencedPreAggregations.length - 1 ? preAggObj.preAggregation.unionWithSourceData : false,\n            rollupLambdaId: `${cube}.${preAggregationName}`,\n            lastRollupLambda: i === referencedPreAggregations.length - 1,\n            rollupLambdaTimeDimensionsReference: preAggObj.references.timeDimensions,\n          }\n        };\n        if (i > 0) {\n          const partitionGranularity = PreAggregations.checkPartitionGranularityDefined(cube, preAggregationName, referencedPreAggregations[i]);\n          const prevReferencedPreAggregation = referencedPreAggregations[i - 1];","sourceCodeStart":1191,"sourceCodeEnd":1227,"githubUrl":"https://github.com/cube-js/cube/blob/7d981676b36392fec34088b9afab6bdcad40207c/packages/cubejs-schema-compiler/src/adapter/PreAggregations.ts#L1191-L1227","documentation":"A rollupLambda pre-aggregation must reference at least one other rollup via its rollups array. If resolving every referenced name (with canUsePreAggregation filtering) yields an empty list, Cube throws this UserError because a lambda with no source rollups has nothing to concatenate.","triggerScenarios":"Defining preAggregations: { myLambda: { type: 'rollupLambda', rollups: [...] } } where the rollups list is empty, references only non-pre-aggregation paths, or all referenced pre-aggregations are filtered out by canUsePreAggregation during buildRollupLambdaPreAggregations.","commonSituations":"Typos in rollup names so the paths don't resolve; rollups array left empty; referencing pre-aggregations that were renamed or removed in a refactor; referencing rollups defined with a query shape that can never be used so all candidates are filtered out.","solutions":["Add at least one valid rollup reference to the rollups array (full path 'CubeName.preAggregationName').","Fix typos in the rollup names so they resolve to existing pre-aggregations.","Check why referenced pre-aggregations are rejected by canUsePreAggregation (query shape mismatch) and align their definitions."],"exampleFix":"// before\npreAggregations: {\n  monthlyUnion: { type: 'rollupLambda', rollups: [] }\n}\n// after\npreAggregations: {\n  monthlyUnion: { type: 'rollupLambda', rollups: [CUBE.ordersByMonth] },\n  ordersByMonth: { measures: [CUBE.count], timeDimension: Orders.createdAt, granularity: 'month' }\n}","handlingStrategy":"validation","validationCode":"// Validate rollupLambda rollups resolve to existing pre-aggregations\nfunction validateRollupLambda(def, schema) {\n  if (def.type === 'rollupLambda') {\n    const resolvable = (def.rollups || []).filter(r => schema.cubeExists(r.split('.')[0]) && schema.preAggregationExists(r));\n    if (resolvable.length === 0) throw new Error('rollupLambda must reference at least one existing rollup');\n  }\n}","typeGuard":"function hasRollupReferences(def) { return def?.type === 'rollupLambda' && Array.isArray(def.rollups) && def.rollups.length > 0; }","tryCatchPattern":"try { await cube.query(query); } catch (e) { if (/should reference at least one rollup/.test(e.message)) { console.error('Add valid entries to the rollups array:', e.message); } else throw e; }","preventionTips":["Never leave rollups: [] in a rollupLambda","Grep for renamed pre-aggregations when refactoring and update rollups arrays","Keep lambda rollups in the same file as their definitions","Add compile-time tests covering every rollupLambda"],"tags":["pre-aggregation","rollup-lambda","empty-reference","schema-compiler"],"backgroundTag":"rollup-lambda-no-references","analyzedSha":"7d981676b36392fec34088b9afab6bdcad40207c","analyzedAt":"2026-09-02T03:45:10.400Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}