cube-js/cube · error · UserError
Pre-aggregation '${preAggregationName}' is already defined
Error message
Pre-aggregation '${preAggregationName}' is already defined What it means
While inserting a new pre-aggregation into a cube's AST preAggregations object, convertJS checks existing property keys; if a property with the same identifier as preAggregationName already exists, it throws UserError 'Pre-aggregation 'name' is already defined' to prevent silent overwrites and duplicate definitions.
Source
Thrown at packages/cubejs-schema-compiler/src/compiler/converters/CubePreAggregationConverter.ts:59
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`);
}
}
});
}
}
});
if (anchor === null) {
cubeDefinition.properties.push(
t.objectProperty(
t.identifier('preAggregations'),
t.objectExpression([t.objectProperty(t.identifier(preAggregationName), preAggregationNode)])
)
);
} else {
(<t.ObjectExpression>anchor).properties.push(
t.objectProperty(t.identifier(preAggregationName), <t.ObjectExpression>preAggregationNode)
);View on GitHub (pinned to 7d981676b3)
Solutions
- Rename the new pre-aggregation to a unique identifier
- Remove or merge the existing pre-aggregation with the same name
- Make generation code idempotent (skip names already present)
- Check for case differences that still resolve to the same identifier
Example fix
// before
preAggregations: {
main: { ... },
main: { ... } // duplicate
}
// after
preAggregations: {
main: { ... },
mainDaily: { ... }
} Defensive patterns
Strategy: validation
Validate before calling
function assertUniquePreAggName(cubeDefinition, preAggregationName) {
const keys = (cubeDefinition.preAggregations && Object.keys(cubeDefinition.preAggregations)) || [];
if (keys.includes(preAggregationName)) {
throw new Error(`Pre-aggregation '${preAggregationName}' would duplicate an existing definition`);
}
} Try / catch
try {
converter.convert(astByCubeName);
} catch (e) {
const m = String(e.message).match(/Pre-aggregation '(.+)' is already defined/);
if (m) console.error(`Rename or merge duplicate rollup: ${m[1]}`);
} Prevention
- Keep a naming convention for auto-generated rollups (e.g. prefix with 'auto_')
- Make schema generators idempotent against existing definitions
- Search schemas for duplicate keys before committing
When it happens
Trigger: Adding or regenerating a pre-aggregation whose name collides with an existing key in the cube's preAggregations object — e.g. creating a rollup named 'main' when 'main' already exists, or re-running an auto-rollup generator against modified schemas.
Common situations: Query-based auto-rollups named after queries colliding with hand-written rollups, duplicated names after copy/pasting definitions between cubes, or re-running schema tooling twice without deduplication.
Related errors
- Can't refresh pre-aggregation without measures and dimension
- No job description provided
- Invalid Job query format: ${error.message || error.toString(
- A user's selector doesn't match any of the pre-aggregations
- The '${query.action}' action type doesn't supported.
AI-assisted analysis of cube-js/cube@7d981676b3 (2026-09-02).
Data as JSON: /api/errors/1714367e67c83656.
Report an issue: GitHub.