cube-js/cube · error · UserError
Ungrouped query requires primary keys to be present in dimen
Error message
Ungrouped query requires primary keys to be present in dimensions: ${missingPrimaryKeys.map(k => `'${k}'`).join(', ')}. Pass allowUngroupedWithoutPrimaryKey option to disable this check. What it means
In ungrouped (raw rows) queries Cube does not aggregate, so it requires that the primary key of every joined cube is present among the dimensions — otherwise rows cannot be uniquely identified and results may be wrong or duplicated. When required primary keys are missing and allowUngroupedWithoutPrimaryKey is not set, it throws this UserError.
Source
Thrown at packages/cubejs-schema-compiler/src/adapter/BaseQuery.js:622
return R.fromPairs(
this.measures.map(m => [m.unescapedAliasName(), m.measure]).concat(
this.dimensions.map(m => [m.unescapedAliasName(), m.dimension])
).concat(
this.timeDimensions.filter(m => !!m.granularity)
.map(m => [m.unescapedAliasName(), `${m.dimension}.${m.granularity}`])
)
);
}
initUngrouped() {
this.ungrouped = this.options.ungrouped;
if (this.ungrouped) {
if (!this.options.allowUngroupedWithoutPrimaryKey && this.join) {
const cubes = R.uniq([this.join.root].concat(this.join.joins.map(j => j.originalTo)));
const primaryKeyNames = cubes.flatMap(c => this.primaryKeyNames(c));
const missingPrimaryKeys = primaryKeyNames.filter(key => !this.dimensions.find(d => d.dimension === key));
if (missingPrimaryKeys.length) {
throw new UserError(`Ungrouped query requires primary keys to be present in dimensions: ${missingPrimaryKeys.map(k => `'${k}'`).join(', ')}. Pass allowUngroupedWithoutPrimaryKey option to disable this check.`);
}
}
if (this.measureFilters.length) {
throw new UserError('Measure filters aren\'t allowed in ungrouped query');
}
}
}
get subQueryDimensions() {
// eslint-disable-next-line no-underscore-dangle
if (!this._subQueryDimensions) {
// eslint-disable-next-line no-underscore-dangle
this._subQueryDimensions = this.collectFromMembers(
false,
this.collectSubQueryDimensionsFor.bind(this),
'collectSubQueryDimensionsFor'
);
}View on GitHub (pinned to 7d981676b3)
Solutions
- Add each listed missing primary key (e.g. 'Orders.id') to the query dimensions
- Set allowUngroupedWithoutPrimaryKey: true in query options to bypass the check (accepting the risk)
- Remove unnecessary joins so fewer primary keys are required
Example fix
// before dimensions: ['Orders.status'], ungrouped: true, joins: [Users] // after dimensions: ['Orders.status', 'Users.id'], ungrouped: true
Defensive patterns
Strategy: validation
Validate before calling
function ensureUngroupedPrimaryKeys(query, primaryKeyOf) {
if (!query.ungrouped) return;
const cubes = joinedCubesOf(query); // from joins + dimensions
const missing = cubes
.map(c => primaryKeyOf(c))
.filter(pk => !query.dimensions.includes(pk));
if (missing.length && !query.allowUngroupedWithoutPrimaryKey) {
query.dimensions.push(...missing);
}
}
ensureUngroupedPrimaryKeys(query, pkIndex); Try / catch
try {
await cubeApi.load(query);
} catch (e) {
if (/Ungrouped query requires primary keys/.test(e.message)) {
const missing = /dimensions: (.+)\./.exec(e.message)[1].split(', ');
query.dimensions.push(...missing);
return cubeApi.load(query);
}
throw e;
} Prevention
- Always include the id dimension of each joined cube in ungrouped queries
- Or pass allowUngroupedWithoutPrimaryKey explicitly when you accept the risk
- Re-check ungrouped queries whenever a join is added
When it happens
Trigger: Running a query with ungrouped mode (e.g. using the raw/ungrouped option or row-level queries) whose join involves cubes whose primary keys are not included in the dimensions list.
Common situations: Building record-detail/drill-down endpoints that select joined cube members but forget to include id dimensions; adding a join to an existing ungrouped query.
Related errors
- Can't parse date: '${from}'
- Can't parse date: '${to}'
- Can't parse date: '${dateString}'
- Invalid Job query format: ${error.message || error.toString(
- Cannot parse selector date range ${selector.dateRange}
AI-assisted analysis of cube-js/cube@7d981676b3 (2026-09-02).
Data as JSON: /api/errors/1e5a95889bb7e05e.
Report an issue: GitHub.