{"record":{"id":"09b0abaf7b15642f","repo":"cube-js/cube","slug":"a-user-s-selector-doesn-t-match-any-of-the-pre-agg","errorCode":null,"errorMessage":"A user's selector doesn't match any of the pre-aggregations defined in the data model.","messagePattern":"A user's selector doesn't match any of the pre-aggregations defined in the data model\\.","errorType":"validation","errorClass":"UserError","httpStatus":null,"severity":"error","filePath":"packages/cubejs-api-gateway/src/gateway.ts","lineNumber":1077,"sourceCode":"      await this.assertApiScope('jobs', req?.context?.securityContext);\n\n      if (!query || Object.keys(query).length === 0) {\n        throw new UserError('No job description provided');\n      }\n\n      const { error, value } = preAggsJobsRequestSchema.validate(query);\n      if (error) {\n        throw new UserError(`Invalid Job query format: ${error.message || error.toString()}`);\n      }\n\n      switch (query.action) {\n        case 'post':\n          result = await this.preAggregationsJobsPOST(\n            context,\n            <PreAggsSelector>value.selector\n          );\n          if (result.length === 0) {\n            throw new UserError(\n              'A user\\'s selector doesn\\'t match any of the ' +\n              'pre-aggregations defined in the data model.'\n            );\n          }\n          break;\n        case 'get':\n          result = await this.preAggregationsJobsGET(\n            context,\n            <string[]>query.tokens,\n            query.resType,\n          );\n          break;\n        default:\n          throw new Error(`The '${query.action}' action type doesn't supported.`);\n      }\n      this.event(`pre_aggregations_jobs_${query.action}`, {\n        source: req.header('source') || 'unknown',\n      });","sourceCodeStart":1059,"sourceCodeEnd":1095,"githubUrl":"https://github.com/cube-js/cube/blob/7d981676b36392fec34088b9afab6bdcad40207c/packages/cubejs-api-gateway/src/gateway.ts#L1059-L1095","documentation":"After a successful 'post' action on the pre-aggregations jobs API, the gateway checks the list of created build jobs. If `preAggregationsJobsPOST` returned an empty array — meaning the selector matched zero pre-aggregations in the compiled data model — this UserError is thrown. It indicates the request was well-formed but nothing in the data model corresponds to the cubes/preAggregations/dataSources you selected.","triggerScenarios":"POST to `/cubejs-system/v1/pre-aggregations/jobs` with `action: 'post'` where the `selector` references cube names, pre-aggregation names (in `Cube.Name` form), or dataSources that don't exist in the current data model — the compiler's `preAggregations()` lookup returns zero entries, so no jobs are queued.","commonSituations":"Typos in cube or pre-aggregation names; referencing pre-aggregations that were renamed or removed from the schema; wrong `dataSource` name in multi-database setups; stale selectors hardcoded in refresh-automation scripts after a data-model refactor; pre-aggregations exist but are filtered out by security context or data source scoping.","solutions":["Verify the exact cube and pre-aggregation names via the metadata API (`GET /cubejs-system/v1/meta`) and use the `CubeName.PreAggregationName` format in `selector.preAggregations`.","Check `selector.dataSources` matches the dataSource keys defined in your `dbType`/`dataSource` configuration (default is 'default').","Remove or correct entries in `selector.cubes`/`selector.preAggregations` that no longer exist in the data model.","Confirm the security context used for the request can see the targeted cubes (multi-tenant setups may hide them).","If pre-aggregations are conditionally defined (e.g., only when `refreshKey` conditions hold), check the compiler logs to see what pre-aggregations were actually compiled."],"exampleFix":"// before\n{ \"action\": \"post\", \"selector\": { \"preAggregations\": [\"Event.Main\"] } }\n\n// after (name fixed to match the data model)\n{ \"action\": \"post\", \"selector\": { \"cubes\": [\"Events\"], \"preAggregations\": [\"Events.Main\"], \"timezones\": [\"UTC\"] } }","handlingStrategy":"validation","validationCode":"async function assertSelectorMatches(metaUrl, headers, selector) {\n  const meta = await (await fetch(metaUrl, { headers })).json();\n  const allPreAggs = new Set(\n    meta.cubes.flatMap(c => (c.preAggregations || []).map(p => `${c.name}.${p.name}`))\n  );\n  const wanted = selector.preAggregations?.length ? selector.preAggregations : [...allPreAggs];\n  const missing = wanted.filter(name => !allPreAggs.has(name));\n  if (wanted.length === 0 || missing.length) {\n    throw new Error(`Selector matches no pre-aggregations; unknown: ${missing.join(', ')}`);\n  }\n}","typeGuard":"function isNonEmptySelector(s: unknown): s is { cubes?: string[]; preAggregations?: string[]; dataSources?: string[]; contexts?: unknown[]; timezones?: string[] } {\n  return !!s && typeof s === 'object' &&\n    (Object.keys(s).length > 0);\n}","tryCatchPattern":"try {\n  const jobs = await postPreAggJobs({ action: 'post', selector });\n} catch (e) {\n  if (String(e.message).includes(\"doesn't match any of the pre-aggregations\")) {\n    // refresh /meta and reconcile selector names before retrying\n    console.error('No pre-aggregations matched selector; check names/dataSources');\n  }\n}","preventionTips":["Always source cube/pre-aggregation names from the /meta endpoint instead of hardcoding them.","Use the exact `CubeName.PreAggregationName` format in selector.preAggregations.","Verify dataSource names in multi-database deployments (default is 'default').","Add a CI check that selector constants in refresh scripts still exist in the current data model."],"tags":["pre-aggregations","rest-api","data-model","selector"],"backgroundTag":"preaggregation-selector-no-match","analyzedSha":"7d981676b36392fec34088b9afab6bdcad40207c","analyzedAt":"2026-09-02T03:45:10.400Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}