{"record":{"id":"938052c3f95cb068","repo":"cube-js/cube","slug":"no-pre-aggregation-table-has-been-built-for-this-q","errorCode":null,"errorMessage":"No pre-aggregation table has been built for this query yet. Please check your refresh worker configuration if it persists.","messagePattern":"No pre-aggregation table has been built for this query yet\\. Please check your refresh worker configuration if it persists\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/cubejs-query-orchestrator/src/orchestrator/QueryOrchestrator.ts","lineNumber":241,"sourceCode":"    }\n\n    const usedPreAggregations = R.pipe<\n      PreAggTableToTempTable[],\n      Record<string, TempTable>,\n      Record<string, unknown>\n    >(\n      R.fromPairs,\n      R.mapObjIndexed((pa: TempTable) => ({\n        targetTableName: pa.targetTableName,\n        refreshKeyValues: pa.refreshKeyValues,\n        lastUpdatedAt: pa.lastUpdatedAt,\n        preAggregationId: pa.preAggregationId,\n        type: pa.type,\n      })),\n    )(preAggregationsTablesToTempTables);\n\n    if (this.rollupOnlyMode && Object.keys(usedPreAggregations).length === 0) {\n      throw new Error(\n        'No pre-aggregation table has been built for this query yet. ' +\n        'Please check your refresh worker configuration if it persists.'\n      );\n    }\n\n    let lastRefreshTimestamp = getLastUpdatedAtTimestamp(\n      preAggregationsTablesToTempTables.map(pa => pa[1].lastUpdatedAt)\n    );\n\n    if (!queryBody.query) {\n      // We want to return a more convenient and filled object for the following\n      // processing for a jobed build query (initialized by the\n      // /cubejs-system/v1/pre-aggregations/jobs endpoint).\n      if (queryBody.isJob) {\n        return preAggregationsTablesToTempTables.map((pa) => ({\n          preAggregation: pa[1].preAggregationId || queryBody.preAggregations[0].preAggregationId,\n          tableName: pa[0],\n          ...pa[1],","sourceCodeStart":223,"sourceCodeEnd":259,"githubUrl":"https://github.com/cube-js/cube/blob/7d981676b36392fec34088b9afab6bdcad40207c/packages/cubejs-query-orchestrator/src/orchestrator/QueryOrchestrator.ts#L223-L259","documentation":"A rollup-only-mode guard in QueryOrchestrator.fetchQuery: with rollupOnlyMode enabled, queries must be answered exclusively from pre-aggregations, and the executed query produced zero used pre-aggregation tables. This means no pre-aggregation matched the query (or none has been built yet for it). If the error persists it indicates the refresh worker is not building the pre-aggregations the queries need.","triggerScenarios":"Thrown at packages/cubejs-query-orchestrator/src/orchestrator/QueryOrchestrator.ts:241 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Check the refresh worker configuration: in rollupOnlyMode the pre-aggregation must be built by a separate refresh worker before queries arrive","Ensure the pre-aggregation build actually succeeded (inspect refresh job logs / system tables) and that the worker shares the same Cube Store and schema","Verify rollupOnlyMode (CUBEJS_ROLLUP_ONLY) is not enabled unintentionally — a full (non-rollup-only) node can build pre-aggregations on demand"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"7d981676b36392fec34088b9afab6bdcad40207c","analyzedAt":"2026-09-02T03:45:10.400Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}