{"record":{"id":"d184385e62bcd1f7","repo":"cube-js/cube","slug":"pre-aggregations-must-be-a-sequence","errorCode":null,"errorMessage":"'pre_aggregations' must be a sequence","messagePattern":"'pre_aggregations' must be a sequence","errorType":"exception","errorClass":"UserError","httpStatus":null,"severity":"error","filePath":"packages/cubejs-schema-compiler/src/compiler/converters/CubePreAggregationConverter.ts","lineNumber":99,"sourceCode":"  protected convertYaml(cubeDefSet: YamlSet) {\n    const { preAggregationName, code } = this.preAggregationDefinition;\n    const { cubeDefinition } = cubeDefSet;\n\n    const preAggDoc = YAML.parseDocument(code);\n    const preAggNode = preAggDoc.contents;\n\n    if (!preAggNode || !isMap(preAggNode)) {\n      throw new UserError('Pre-aggregation YAML must be a map/object');\n    }\n\n    const preAggsPair = cubeDefinition.items.find(\n      (pair: Pair) => isScalar(pair.key) && (pair.key.value === 'pre_aggregations' || pair.key.value === 'preAggregations')\n    );\n\n    if (preAggsPair) {\n      const seq = preAggsPair.value;\n      if (!YAML.isSeq(seq)) {\n        throw new UserError('\\'pre_aggregations\\' must be a sequence');\n      }\n\n      const exists = seq.items.some(item => {\n        if (isMap(item)) {\n          const namePair = item.items.find(\n            (pair: Pair) => isScalar(pair.key) && pair.key.value === 'name'\n          );\n          return namePair && isScalar(namePair.value) && namePair.value.value === preAggregationName;\n        }\n        return false;\n      });\n\n      if (exists) {\n        throw new UserError(`Pre-aggregation '${preAggregationName}' is already defined`);\n      }\n\n      seq.items.push(preAggNode);\n    } else {","sourceCodeStart":81,"sourceCodeEnd":117,"githubUrl":"https://github.com/cube-js/cube/blob/7d981676b36392fec34088b9afab6bdcad40207c/packages/cubejs-schema-compiler/src/compiler/converters/CubePreAggregationConverter.ts#L81-L117","documentation":"Cube's YAML data model converter requires the top-level 'pre_aggregations' (or 'preAggregations') key to hold a YAML sequence (list) of pre-aggregation definitions. This library throws when the value under that key is a scalar or a map instead of a list, because it iterates seq.items to extract per-pre-aggregation names.","triggerScenarios":"Defining pre_aggregations as a YAML mapping (e.g. `pre_aggregations:\\n  main: ...`), as a scalar string, or with wrong indentation so the parsed node is not a YAMLSeq, while converting a YAML schema file via CubeSchemaConverter.convertYaml.","commonSituations":"Hand-written YAML data models where pre_aggregations was indented as a map instead of a list item; copying JS-style named pre-aggregations (`main: {...}`) into YAML without the `- ` list prefix; tabs/indentation errors making the parser see a map.","solutions":["Rewrite pre_aggregations as a YAML sequence: each pre-aggregation starts with `- ` under the key","Check indentation — pre_aggregations must be a sibling key of the cube, and its items indented with '- '","If migrating from JS schema, remember YAML names go inside each item's 'name:' field, not as map keys"],"exampleFix":"# before\npre_aggregations:\n  main:\n    measures: [visitors.count]\n# after\npre_aggregations:\n  - name: main\n    measures:\n      - visitors.count","handlingStrategy":"validation","validationCode":"function assertPreAggregationsIsList(cube) {\n  const v = cube.pre_aggregations ?? cube.preAggregations;\n  if (v != null && !Array.isArray(v)) {\n    throw new Error(\"'pre_aggregations' must be a list of pre-aggregation objects\");\n  }\n}","typeGuard":"const isPreAggSeq = (v) => Array.isArray(v) || (v && typeof v.items === 'object');","tryCatchPattern":"try {\n  converter.convert(cubeDef);\n} catch (e) {\n  if (e.message.includes(\"'pre_aggregations' must be a sequence\")) {\n    console.error('Fix YAML: pre_aggregations items must start with \"- \"');\n  }\n  throw e;\n}","preventionTips":["Always prefix each pre-aggregation in YAML with '- '","Keep JS-style named maps out of YAML models — use 'name:' inside list items","Lint YAML data models with Cube's compiler in CI to catch shape errors early"],"tags":["yaml","schema","validation"],"backgroundTag":"yaml-schema-shape-mismatch","analyzedSha":"7d981676b36392fec34088b9afab6bdcad40207c","analyzedAt":"2026-09-02T03:45:10.400Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}