{"record":{"id":"019348c8ef102bef","repo":"cube-js/cube","slug":"load-cache-tries-to-load-table-preaggregation-ta","errorCode":null,"errorMessage":"Load cache tries to load table ${preAggregation.tableName} outside of tablePrefixes filter: ${this.tablePrefixes.join(', ')}","messagePattern":"Load cache tries to load table (.+?) outside of tablePrefixes filter: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/cubejs-query-orchestrator/src/orchestrator/PreAggregationLoadCache.ts","lineNumber":181,"sourceCode":"      const contentKey = `${e.table_name}_${e.content_version}`;\n      if (!byContent[contentKey]) {\n        byContent[contentKey] = e;\n      }\n      const structureKey = `${e.table_name}_${e.structure_version}`;\n      if (!byStructure[structureKey]) {\n        byStructure[structureKey] = e;\n      }\n      if (!byTableName[e.table_name]) {\n        byTableName[e.table_name] = e;\n      }\n    });\n\n    return { versionEntries, byContent, byStructure, byTableName };\n  }\n\n  public async getVersionEntries(preAggregation): Promise<VersionEntriesObj> {\n    if (this.tablePrefixes && !this.tablePrefixes.find(p => preAggregation.tableName.split('.')[1].startsWith(p))) {\n      throw new Error(`Load cache tries to load table ${preAggregation.tableName} outside of tablePrefixes filter: ${this.tablePrefixes.join(', ')}`);\n    }\n    const redisKey = this.tablesCachePrefixKey(preAggregation);\n    if (!(await this.versionEntries[redisKey])) {\n      this.versionEntries[redisKey] = this.calculateVersionEntries(preAggregation).catch(e => {\n        delete this.versionEntries[redisKey];\n        throw e;\n      });\n    }\n    return this.versionEntries[redisKey];\n  }\n\n  public async keyQueryResult(sqlQuery: QueryWithParams, waitForRenew: boolean, priority: QueuePriority) {\n    const memoKey = this.queryCache.refreshKeyCacheKey(sqlQuery, this.dataSource);\n\n    if (!this.queryResults[memoKey]) {\n      this.queryResults[memoKey] = await this.queryCache.cacheRefreshKeyResult(\n        sqlQuery,\n        60 * 60,","sourceCodeStart":163,"sourceCodeEnd":199,"githubUrl":"https://github.com/cube-js/cube/blob/7d981676b36392fec34088b9afab6bdcad40207c/packages/cubejs-query-orchestrator/src/orchestrator/PreAggregationLoadCache.ts#L163-L199","documentation":"PreAggregationLoadCache tracks which pre-aggregation tables this instance is allowed to load, filtered by tablePrefixes. getVersionEntries throws if preAggregation.tableName's schema-qualified name does not start with any allowed prefix. This is an internal safety check: it indicates the orchestrator is trying to fetch version entries for a pre-aggregation that was not selected for this load.","triggerScenarios":"Calling getVersionEntries with a pre-aggregation whose tableName split('.')[1] (table name after schema) does not start with any string in this.tablePrefixes; tablePrefixes was set (non-null) but the pre-aggregation comes from a different partition/scope.","commonSituations":"Refresh worker and API instance with mismatched partition prefixes; custom orchestration code passing pre-aggregations outside the filter; multi-tenant deployments where a table name doesn't match expected prefixes.","solutions":["Verify the pre-aggregation belongs to the current load scope; do not call load for pre-aggregations outside tablePrefixes.","Align tablePrefixes between the API instance and refresh worker so both use the same partition filter.","Check the pre-aggregation's tableName (schema.table) matches your prefix expectations — the check tests only the part after the first '.'.","If prefixes were set unintentionally, clear/adjust the options that pass tablePrefixes into PreAggregationLoadCache."],"exampleFix":"// before\npreAggregations: { tablePrefixes: ['my_schema.agg_'] } // tableName 'other_schema.agg_x' fails\n// after\npreAggregations: { tablePrefixes: ['my_schema.agg_', 'other_schema.agg_'] }","handlingStrategy":"validation","validationCode":"function withinPrefixes(tableName, prefixes) {\n  const table = String(tableName).split('.')[1] || '';\n  return !prefixes || prefixes.some(p => table.startsWith(p));\n}\nif (!withinPrefixes(preAggregation.tableName, loadCache.tablePrefixes)) throw new Error('pre-aggregation outside tablePrefixes');","typeGuard":"function isWithinTablePrefixes(t) {\n  return typeof t === 'string' &&\n    t.includes('.') &&\n    (this.tablePrefixes == null || this.tablePrefixes.some(p => t.split('.')[1].startsWith(p)));\n}","tryCatchPattern":"try {\n  const entries = await loadCache.getVersionEntries(preAggregation);\n} catch (e) {\n  if (String(e.message).includes('outside of tablePrefixes')) {\n    console.error('Pre-aggregation scope mismatch:', preAggregation.tableName);\n  }\n  throw e;\n}","preventionTips":["Keep tablePrefixes consistent across all orchestrator instances and refresh workers.","Derive prefixes from your schema configuration instead of hardcoding.","Log pre-aggregation table names when a partition filter is applied.","Only load pre-aggregations produced by the same partition query."],"tags":["pre-aggregation","table-prefixes","internal-invariant"],"backgroundTag":"preaggregation-table-prefix-mismatch","analyzedSha":"7d981676b36392fec34088b9afab6bdcad40207c","analyzedAt":"2026-09-02T03:45:10.400Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}