cube-js/cube · error
Lambda union with source data feature is supported only by…
Error message
Lambda union with source data feature is supported only by external rollups stored in Cube Store but was invoked for '${preAggregation.preAggregationId}' What it means
Cube's lambda (multi-stage) pre-aggregations that union over source data require the resulting rollup to be stored in Cube Store (an external store). getTableColumnTypes throws this when it is asked for column types of a table marked external=true while the skipExternalCacheAndQueue option is set, meaning the code path assumed a non-Cube-Store external rollup. It protects an internal invariant: source-data lambda unions are only valid for external rollups physically stored in Cube Store.
Solutions
- Store the rollup in Cube Store: make sure the lambda union pre-aggregation is built as an external rollup (external: true in the rollup config and a Cube Store external store configured).
- Remove or unset the skipExternalCacheAndQueue option so external cache and queue are used.
- Restructure the pre-aggregation so lambda union source data is not required, or build the base pre-aggregation first (pre-aggregation chaining) instead of reading source data.
- Check the rollup definition: source data lambda unions require a partitioned base pre-aggregation; define it and reference it instead of raw source data.
Example fix
// before
options: { skipExternalCacheAndQueue: true }
// after
options: { skipExternalCacheAndQueue: false } // rollup stored in Cube Store Defensive patterns
Strategy: validation
Validate before calling
const opts = preAggregationsOptions || {};
if (rollupConfig.rollup_lambda && rollupConfig.external !== false && opts.skipExternalCacheAndQueue) {
throw new Error('Lambda union with source data requires Cube Store external rollups; unset skipExternalCacheAndQueue');
} Try / catch
try {
await loadCache.getTableColumnTypes(preAggregation, tableName);
} catch (e) {
if (String(e.message).includes('Lambda union with source data')) {
// fall back to building in Cube Store or restructure rollup
}
throw e;
} Prevention
- Always store lambda union rollups in Cube Store (external: true).
- Never enable skipExternalCacheAndQueue for lambda unions with source data.
- Define a base pre-aggregation for the lambda union instead of reading raw source rows.
- Document external store requirements in your Cube configuration review checklist.
When it happens
Trigger: Calling getTableColumnTypes for a preAggregation with external=true when this.preAggregations.options.skipExternalCacheAndQueue is truthy; configuring a lambda union pre-aggregation that rolls up to a non-Cube-Store external store while external caching/queue is skipped.
Common situations: Running a query whose pre-aggregation chain uses source data with a custom external driver configuration; test setups or options that set skipExternalCacheAndQueue; misconfigured rollups where externalFrom/external store does not point at Cube Store.
Related errors
- Only fixed rolling windows are supported by Cube Store but…
- The maximum number of source rows
- Unsupported export bucket type
- A user-defined contextToApiScopes function returns an…
- A user-defined contextToApiScopes function returns a wrong…
AI-assisted analysis of cube-js/cube@7d981676b3 (2026-09-02).
Data as JSON: /api/errors/468e7f099b0848ff.
Report an issue: GitHub.
Appendix: source
Thrown at packages/cubejs-query-orchestrator/src/orchestrator/PreAggregationLoadCache.ts:130
protected async getTablesQuery(preAggregation) {
const redisKey = this.tablesCachePrefixKey(preAggregation);
if (!this.tables[redisKey]) {
const tables = this.preAggregations.options.skipExternalCacheAndQueue && preAggregation.external ?
await this.fetchTablesNoCache(preAggregation) :
await this.tablesFromCache(preAggregation);
if (tables === undefined) {
throw new Error('Pre-aggregation tables are undefined.');
}
this.tables[redisKey] = tables;
}
return this.tables[redisKey];
}
public async getTableColumnTypes(preAggregation: PreAggregationDescription, tableName: string): Promise<TableStructure> {
const prefixKey = this.tablesCachePrefixKey(preAggregation);
if (!this.tableColumnTypes[prefixKey]?.[tableName]) {
if (!this.preAggregations.options.skipExternalCacheAndQueue && preAggregation.external) {
throw new Error(`Lambda union with source data feature is supported only by external rollups stored in Cube Store but was invoked for '${preAggregation.preAggregationId}'`);
}
const client = await this.externalDriverFactory();
const columnTypes = await client.tableColumnTypes(tableName);
if (!this.tableColumnTypes[prefixKey]) {
this.tableColumnTypes[prefixKey] = {};
}
this.tableColumnTypes[prefixKey][tableName] = columnTypes;
}
return this.tableColumnTypes[prefixKey][tableName];
}
private async calculateVersionEntries(preAggregation): Promise<VersionEntriesObj> {
let versionEntries = tablesToVersionEntries(
preAggregation.preAggregationsSchema,
await this.getTablesQuery(preAggregation)
);
// It presumes strong consistency guarantees for external pre-aggregation tables ingestion
if (!preAggregation.external) {View on GitHub (pinned to 7d981676b3)