{"record":{"id":"96866cca901686cf","repo":"cube-js/cube","slug":"to-join-across-data-sources-use-rollupjoin-with-cu","errorCode":null,"errorMessage":"To join across data sources use rollupJoin with Cube Store. If rollupJoin is defined, this error indicates it doesn't match the query. Please use Rollup Designer to verify it's definition. Found data sources: ${dataSources.join(', ')}","messagePattern":"To join across data sources use rollupJoin with Cube Store\\. If rollupJoin is defined, this error indicates it doesn't match the query\\. Please use Rollup Designer to verify it's definition\\. Found data sources: (.+?)","errorType":"exception","errorClass":"UserError","httpStatus":null,"severity":"error","filePath":"packages/cubejs-schema-compiler/src/adapter/BaseQuery.js","lineNumber":594,"sourceCode":"      if (Array.isArray(hint)) {\n        return hint;\n      }\n\n      for (const path of allPaths) {\n        const hintIndex = path.indexOf(hint);\n        if (hintIndex !== -1) {\n          return path.slice(0, hintIndex + 1);\n        }\n      }\n\n      return hint;\n    });\n  }\n\n  get dataSource() {\n    const dataSources = R.uniq(this.allCubeNames.map(c => this.cubeDataSource(c)));\n    if (dataSources.length > 1 && !this.externalPreAggregationQuery()) {\n      throw new UserError(`To join across data sources use rollupJoin with Cube Store. If rollupJoin is defined, this error indicates it doesn't match the query. Please use Rollup Designer to verify it's definition. Found data sources: ${dataSources.join(', ')}`);\n    }\n    return dataSources[0];\n  }\n\n  cubeDataSource(cube) {\n    return this.cubeEvaluator.cubeFromPath(cube).dataSource || 'default';\n  }\n\n  get aliasNameToMember() {\n    return R.fromPairs(\n      this.measures.map(m => [m.unescapedAliasName(), m.measure]).concat(\n        this.dimensions.map(m => [m.unescapedAliasName(), m.dimension])\n      ).concat(\n        this.timeDimensions.filter(m => !!m.granularity)\n          .map(m => [m.unescapedAliasName(), `${m.dimension}.${m.granularity}`])\n      )\n    );\n  }","sourceCodeStart":576,"sourceCodeEnd":612,"githubUrl":"https://github.com/cube-js/cube/blob/7d981676b36392fec34088b9afab6bdcad40207c/packages/cubejs-schema-compiler/src/adapter/BaseQuery.js#L576-L612","documentation":"The query's dataSource getter collects the distinct data sources of all cubes involved. If more than one data source is found and the query is not an external (rollupJoin) pre-aggregation query, Cube cannot execute it on a single connection and throws, telling you rollupJoin with Cube Store is required for cross-source joins.","triggerScenarios":"A query combining members from cubes with different 'dataSource' values (e.g. 'default' and 'warehouseB') without a matching rollupJoin pre-aggregation, or with externalPreAggregationQuery() false.","commonSituations":"Federating tables from two databases (e.g. Postgres + BigQuery) in one query, forgetting to set dataSource on a new cube so it defaults differently, or a rollupJoin definition that doesn't match the query's members.","solutions":["Restrict the query to cubes sharing the same dataSource","Define a correct rollupJoin pre-aggregation and ensure external pre-agigrations/Cube Store are enabled","Set the dataSource property explicitly on every cube so they align","Use the Rollup Designer to verify the rollupJoin definition matches the query"],"exampleFix":"// before (cube in another DB, no rollupJoin)\ncube: `FinanceBudget`, sql: `SELECT * FROM budget_db.budget`\n// after\ncube: `FinanceBudget`, sql: `SELECT * FROM budget_db.budget`, dataSource: 'budget',\nrollups: { /* rollupJoin matching the queried members via Cube Store */ }","handlingStrategy":"validation","validationCode":"// pre-flight: ensure all queried cubes share one dataSource (client-side meta check)\nconst sources = new Set(queryMembers.map(m => dataSourceOfCube(m.split('.')[0])));\nif (sources.size > 1 && !hasMatchingRollupJoin(query)) {\n  throw new Error(`Cross-source query needs rollupJoin: ${[...sources].join(', ')}`);\n}","typeGuard":null,"tryCatchPattern":"try {\n  return await cubeApi.load(query);\n} catch (e) {\n  if (/To join across data sources/.test(e.message)) {\n    const sources = /Found data sources: (.+)$/.exec(e.message)?.[1];\n    throw new Error(`Restrict query to one data source or define rollupJoin (found: ${sources})`);\n  }\n  throw e;\n}","preventionTips":["Set dataSource explicitly on every cube","Document which cubes live in which database for query authors","Use rollupJoin pre-aggregations with Cube Store for intentional cross-source queries","Verify rollupJoin definitions in Rollup Designer after schema changes"],"tags":["data-sources","joins","rollupjoin"],"backgroundTag":"cross-datasource-join-not-supported","analyzedSha":"7d981676b36392fec34088b9afab6bdcad40207c","analyzedAt":"2026-09-02T03:45:10.400Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}