nocobase/nocobase · error · FlowSurfaceBadRequestError
chart query.sorting does not support aggregated measure outp
Error message
chart query.sorting does not support aggregated measure outputs or custom measure aliases in builder mode
What it means
In builder mode, runtime sorting cannot target aggregated measure outputs or custom measure aliases because the aggregation happens after row-level data is fetched, so the runtime cannot order by those computed columns. The validator builds a set of unsupported measure output aliases (unsupportedMeasureOutputs) and rejects any sorting item referencing them.
Source
Thrown at packages/plugins/@nocobase/plugin-flow-engine/src/server/flow-surfaces/chart-config.ts:1211
return;
}
const unsupportedMeasureOutputs = new Set<string>();
for (const measure of _.castArray(query?.measures || [])) {
const outputAlias = aliasOfSelection(measure);
const rawFieldAlias = aliasOfFieldValue(measure?.field);
if (!outputAlias) {
continue;
}
if (measure?.aggregation || (rawFieldAlias && outputAlias !== rawFieldAlias)) {
unsupportedMeasureOutputs.add(outputAlias);
}
}
for (const item of sorting) {
const sortingField = aliasOfFieldValue(item?.field);
if (sortingField && unsupportedMeasureOutputs.has(sortingField)) {
throw new FlowSurfaceBadRequestError(
'chart query.sorting does not support aggregated measure outputs or custom measure aliases in builder mode',
);
}
}
}
function normalizeBuilderQuery(query: Record<string, any>) {
const resource = normalizeMergedChartResource(query, { required: true });
const dimensions = _.isUndefined(query.dimensions)
? undefined
: Array.isArray(query.dimensions)
? query.dimensions.map((item, index) => normalizeChartDimension(item, index))
: (() => {
throw new FlowSurfaceBadRequestError('chart query.dimensions must be an array');
})();
const measures = Array.isArray(query.measures)
? query.measures
.map((item, index) => normalizeChartMeasure(item, index))View on GitHub (pinned to fa42722fef)
Solutions
- Remove the sorting entry that references the aggregated measure and sort client-side after data retrieval.
- Sort by a dimension instead (e.g. by the category/date field) if the business goal allows.
- If aggregate sorting is essential, switch the chart query to mode='sql' where ORDER BY on aggregates is supported.
Example fix
// before
measures: [{ field: 'amount', aggregate: 'sum', alias: 'total' }], sorting: [{ field: 'total' }]
// after
measures: [{ field: 'amount', aggregate: 'sum', alias: 'total' }]
// no sorting; sort rows in the client after fetching Defensive patterns
Strategy: validation
Validate before calling
function validateNoAggregatedSorting(query) {
const aggregatedAliases = new Set(
query.measures.filter((m) => m.aggregate || m.alias !== m.field).map((m) => m.alias || m.field),
);
for (const item of query.sorting || []) {
if (aggregatedAliases.has(item.field)) {
throw new Error(`cannot sort by aggregated measure '${item.field}' in builder mode`);
}
}
} Type guard
function isSortableMeasure(m: { aggregate?: string; alias?: string; field: string }): boolean {
return !m.aggregate && (m.alias ?? m.field) === m.field;
} Try / catch
try {
return await runChartQuery(query);
} catch (err) {
if (err?.message?.includes('aggregated measure outputs')) {
const safe = { ...query, sorting: (query.sorting || []).filter((s) => !isMeasureAlias(query, s.field)) };
return runChartQuery(safe);
}
throw err;
} Prevention
- Only offer dimension fields in sort dropdowns for builder-mode charts.
- Sort aggregated results client-side after fetching when descending-by-total is needed.
- Switch to mode='sql' explicitly when ORDER BY on aggregates is a hard requirement.
When it happens
Trigger: A builder-mode chart query with measures that aggregate (sum/count/avg etc.) or define custom aliases, combined with query.sorting whose field alias matches one of those aggregated/custom measure outputs.
Common situations: Trying to sort a bar chart descending by a summed revenue measure; sorting by a count(*) alias; templates migrated from SQL-mode charts where ORDER BY on aggregates was legal.
Related errors
- chart query.sorting only supports selected dimension/measure
- chart query.sorting must be an array
- Invalid aggregation function: ${aggregation}
- sql is required
- collection and measures are required
AI-assisted analysis of nocobase/nocobase@fa42722fef (2026-09-01).
Data as JSON: /api/errors/4f91379db748d299.
Report an issue: GitHub.