cube-js/cube · error · UserError
Query should contain either measures, dimensions or timeDime
Error message
Query should contain either measures, dimensions or timeDimensions with granularities in order to be valid
What it means
Semantic validation in normalizeQuery: after schema validation passes, the query is rejected because it contains no measures, no dimensions, and no timeDimensions with granularities — i.e. nothing to select, so it cannot produce a valid result set.
Source
Thrown at packages/cubejs-api-gateway/src/query.js:447
* @param {Query} query
* @param {boolean} persistent
* @param {CacheMode} [cacheMode]
* @throws {UserError}
* @returns {import('./types/query').NormalizedQuery}
*/
const normalizeQuery = (query, persistent, cacheMode) => {
query = normalizeQueryCacheMode(query, cacheMode);
query.timezone = query.timezone || getEnv('defaultTimezone');
const { error, value } = querySchema.validate(query);
if (error) {
throw new UserError(`Invalid query format: ${error.message || error.toString()}`);
}
const validQuery = query.measures?.length ||
query.dimensions?.length ||
query.timeDimensions?.filter(td => !!td.granularity).length;
if (!validQuery) {
throw new UserError(
'Query should contain either measures, dimensions or timeDimensions with granularities in order to be valid'
);
}
const regularToTimeDimension = (query.dimensions || []).filter(d => typeof d === 'string' && d.split('.').length === 3).map(d => ({
dimension: d.split('.').slice(0, 2).join('.'),
granularity: d.split('.')[2]
}));
const timezone = value.timezone || 'UTC';
const def = getEnv('dbQueryDefaultLimit') <= getEnv('dbQueryLimit')
? getEnv('dbQueryDefaultLimit')
: getEnv('dbQueryLimit');
let newLimit;
if (!persistent) {
if (
typeof query.limit === 'number' &&View on GitHub (pinned to 7d981676b3)
Solutions
- Add at least one measure, dimension, or a timeDimension with a granularity to the query.
- If the query was built dynamically, check the code path that produced an empty selection set.
- Use the /meta endpoint to verify the member names you are adding actually exist.
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at packages/cubejs-api-gateway/src/query.js:447 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of cube-js/cube@7d981676b3 (2026-09-02).
Data as JSON: /api/errors/4b5fb4bb3c4a93ac.
Report an issue: GitHub.