cube-js/cube · error · UserError
You cannot use dimension and measure in same condition: ${JS
Error message
You cannot use dimension and measure in same condition: ${JSON.stringify(f)} What it means
When compiling the filter tree, Cube classifies each leaf as filtering either a dimension or a measure. A single condition referencing both a dimension and a measure is ambiguous for SQL generation (it mixes row-level and aggregate-level predicates), so the library rejects it with this UserError.
Source
Thrown at packages/cubejs-schema-compiler/src/adapter/BaseQuery.js:228
dimensionGroup: true,
measure: null,
};
}
if (!dimension.length && measure.length) {
return {
values: this.extractFiltersAsTree(f[operator]),
operator,
dimension: null,
measureGroup: true,
};
}
if (!dimension.length && !measure.length) {
return {
values: [],
operator,
};
}
throw new UserError(`You cannot use dimension and measure in same condition: ${JSON.stringify(f)}`);
}
if (!f.member && !f.dimension) {
throw new UserError(`member attribute is required for filter ${JSON.stringify(f)}`);
}
if (this.cubeEvaluator.isMeasure(f.member || f.dimension)) {
return Object.assign({}, f, {
dimension: null,
measure: f.member || f.dimension
});
}
return Object.assign({}, f, {
measure: null,
dimension: f.member || f.dimension
});
});View on GitHub (pinned to 7d981676b3)
Solutions
- Split the condition: dimension filters and measure filters must be separate filter nodes
- Put measure conditions in the 'filters' acting on measures or in having-style position, not mixed in one leaf
- Check filter-building code that merges member lists into a single object
Example fix
// before
{ member: ['Orders.status', 'Orders.count'], operator: 'equals', values: ['shipped', 10] }
// after
filters: [
{ member: 'Orders.status', operator: 'equals', values: ['shipped'] },
{ member: 'Orders.count', operator: 'equals', values: [10] }
] Defensive patterns
Strategy: validation
Validate before calling
// split mixed leaves before sending
function splitMixedFilters(filters, isMeasure) {
return filters.flatMap(f => {
const members = [].concat(f.member || f.dimension || []);
if (members.some(isMeasure) && members.some(m => !isMeasure(m))) {
return members.map(m => ({ ...f, member: m }));
}
return [f];
});
}
query.filters = splitMixedFilters(query.filters, isKnownMeasure); Type guard
const isPureDimOrMeasure = (f, isMeasure) => {
const ms = [].concat(f.member || f.dimension || []);
const hasDim = ms.some(m => !isMeasure(m));
const hasMea = ms.some(isMeasure);
return !(hasDim && hasMea);
}; Try / catch
try {
await cubeApi.load(query);
} catch (e) {
if (/dimension and measure in same condition/.test(e.message)) {
// split the filter into separate conditions and retry once
} else throw e;
} Prevention
- Keep one member per filter leaf
- Separate dimension filters from measure (having) filters in your UI/state model
- Never merge filter nodes by concatenating member arrays across types
When it happens
Trigger: A leaf filter whose resolved members include at least one dimension and at least one measure simultaneously (e.g. f.dimension plus a measure member, or an 'or'/'and' leaf mixing them via member arrays), with an operator that produced non-empty lists for both.
Common situations: Building combined filter UIs where users can pick both attributes and metrics in one condition; programmatic filter merging that concatenates dimension and measure members into one node.
Related errors
- member attribute is required for filter ${JSON.stringify(f)}
- compareDateRange can only exist for one timeDimension
- Granularity "${timeDimension.granularity}" not found in time
- Expected one parameter but nothing found
- Expected only 2 parameters for timestamp filter but got: ${t
AI-assisted analysis of cube-js/cube@7d981676b3 (2026-09-02).
Data as JSON: /api/errors/b74c55dbf97c204e.
Report an issue: GitHub.