cube-js/cube · error · Error
Pre-aggregation definition is malformed
Error message
Pre-aggregation definition is malformed
What it means
CubePreAggregationConverter.convertJS parses a pre-aggregation definition snippet with Babel and expects the first statement to be an object expression ({ ... }). If the parsed code is not an object expression (or fails that shape check), a plain Error 'Pre-aggregation definition is malformed' is thrown during AST-based pre-aggregation conversion.
Source
Thrown at packages/cubejs-schema-compiler/src/compiler/converters/CubePreAggregationConverter.ts:46
}
protected convertJS(cubeDefSet: JsSet) {
const { preAggregationName, code } = this.preAggregationDefinition;
const { cubeDefinition } = cubeDefSet;
let preAggregationNode: t.ObjectExpression | null = null;
const preAggregationAst = parse(`(${code})`);
if (t.isExpressionStatement(preAggregationAst.program.body[0])) {
const [statement] = preAggregationAst.program.body;
if (t.isObjectExpression(statement.expression)) {
preAggregationNode = statement.expression;
}
}
if (preAggregationNode === null) {
throw new Error('Pre-aggregation definition is malformed');
}
let anchor: t.ObjectExpression | null = null;
cubeDefinition.properties.forEach((prop) => {
if (t.isObjectProperty(prop) && t.isIdentifier(prop.key)) {
if (prop.key.name === 'preAggregations' && t.isObjectExpression(prop.value)) {
anchor = prop.value;
prop.value.properties.forEach((p) => {
if (t.isObjectProperty(p) && t.isIdentifier(p.key)) {
if (p.key.name === preAggregationName) {
throw new UserError(`Pre-aggregation '${preAggregationName}' is already defined`);
}
}
});
}
}View on GitHub (pinned to 7d981676b3)
Solutions
- Ensure the pre-aggregation code is a complete object literal, e.g. { measures: [...], timeDimension: ..., granularity: 'day' }
- Log/inspect the code string passed to the converter before conversion
- Wrap non-expression snippets in parentheses/braces so Babel parses them as ObjectExpression
- Catch and report this Error upstream since it is a plain Error, not UserError
Example fix
// before
const code = "rollups => rollups.main()";
// after
const code = "{ measures: [orders.count], timeDimension: orders.createdAt, granularity: 'day' }"; Defensive patterns
Strategy: validation
Validate before calling
const { parse } = require('@babel/parser');
const t = require('@babel/types');
function isObjectLiteralDefinition(code) {
const ast = parse(`(${code})`);
const [stmt] = ast.program.body;
return t.isExpressionStatement(stmt) && t.isObjectExpression(stmt.expression);
} Try / catch
try {
converter.convert(astByCubeName);
} catch (e) {
if (e.message === 'Pre-aggregation definition is malformed') {
console.error('Pre-aggregation code must be an object literal');
}
} Prevention
- Always pass complete '{ ... }' object literals as pre-aggregation code
- Validate the generated code string before conversion
- Beware plain Errors here (not UserError) — catch generically in tooling
When it happens
Trigger: Submitting a preAggregations definition whose code parses to something other than an object literal — e.g. a function call, identifier, array, or empty snippet — via the schema converter API or playground pre-aggregation flows.
Common situations: Programmatic pre-aggregation creation where the code string was truncated or built incorrectly, IDE copy/paste dropping the braces, or passing a function-style definition where an object is required.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Invalid Job query format: ${error.message || error.toString(
- Cannot parse selector date range ${selector.dateRange}
- Pre-aggregation YAML must be a map/object
- Can't parse date: '${from}'
- Can't parse date: '${to}'
AI-assisted analysis of cube-js/cube@7d981676b3 (2026-09-02).
Data as JSON: /api/errors/2cb04a6f12ed7ab4.
Report an issue: GitHub.