X_AGGREGATE_MIXED_CURRENCY
Means
an amount was aggregated across currencies
Typical cause
100 JPY and 100 EUR have no common unit, so a sum, min or max over them answers a number in no currency at all. Both drivers count the distinct currencies of the rows they are about to aggregate and refuse past one, rather than answering in whichever came first; the cause lists every currency it found. One currency at two scales is the same refusal with its own words and its own fix — the cause says 2 scales of USD, and a currency filter would keep both rows
Fix
<entity>.andWhere('<col>.currency', 'eq', '<CUR>').<fn>('<col>') — one currency per call — or countBy('<col>.currency') first to see the split. For a scale mix: for await (const rows of <entity>.inBatches(1000)) { … }, folding at one scale in the app