actualbudget/actual · error
Unsupported summary type
Error message
Unsupported summary type
What it means
summarySpreadsheet switches on summaryContent.type to compute the summary value (sum, avgPerTransact, avgPerMonth, avgPerYear, percentage). If the type matches none of the known cases, the default branch throws 'Unsupported summary type'. This guards against stale or invalid SummaryContent configs reaching the spreadsheet builder.
Source
Thrown at packages/desktop-client/src/components/reports/spreadsheets/summary-spreadsheet.ts:182
...calculatePerYear(data.data, startDay, endDay),
});
break;
}
case 'percentage':
setData({
...dateRanges,
...(await calculatePercentage(
data.data,
summaryContent,
startDay,
endDay,
)),
});
break;
default:
throw new Error(`Unsupported summary type`);
}
};
}
function calculatePerMonth(
data: Array<{
date: string;
amount: number;
count: number;
}>,
months: Date[],
) {
if (!data.length || !months.length) {
return { total: 0, dividend: 0, divisor: 0 };
}
const monthlyData = data.reduce(
(acc, day) => {View on GitHub (pinned to d4334cb6e6)
Solutions
- Inspect summaryContent.type at the call site and use one of the supported values: sum, avgPerTransact, avgPerMonth, avgPerYear, percentage
- If the config is persisted, migrate or re-create the summary widget so it stores a valid type
- Narrow the input with the SummaryContent type union and let TypeScript catch invalid types at compile time
- Wrap in try/catch and render a fallback message for unknown summary types
Example fix
// before
summarySpreadsheet(start, end, conditions, op, { type: 'average' } as SummaryContent, locale);
// after
summarySpreadsheet(start, end, conditions, op, { type: 'avgPerMonth' } satisfies SummaryContent, locale); Defensive patterns
Strategy: type-guard
Validate before calling
const SUPPORTED = ['sum','avgPerTransact','avgPerMonth','avgPerYear','percentage'] as const;
if (!SUPPORTED.includes(summaryContent.type)) throw new Error(`Unsupported summary type: ${summaryContent.type}`); Type guard
function isSummaryType(t: unknown): t is 'sum' | 'avgPerTransact' | 'avgPerMonth' | 'avgPerYear' | 'percentage' {
return typeof t === 'string' && ['sum','avgPerTransact','avgPerMonth','avgPerYear','percentage'].includes(t);
} Try / catch
try {
await builder(spreadsheet, setData);
} catch (e) {
if (e instanceof Error && e.message.startsWith('Unsupported summary type')) {
setData({ total: 0, divisor: 0, dividend: 0, fromRange: '', toRange: '' });
} else throw e;
} Prevention
- Type summaryContent as SummaryContent so the union is enforced at compile time
- Validate persisted dashboard configs on load and migrate unknown types
- Never construct SummaryContent objects with untyped string literals
- Test spreadsheet builders against every member of the type union
When it happens
Trigger: Passing a summaryContent object whose type is not one of 'sum' | 'avgPerTransact' | 'avgPerMonth' | 'avgPerYear' | 'percentage' — e.g. a typo like 'avgpermonth', an old serialized config from a previous schema, or a new type added in the UI before the spreadsheet supports it.
Common situations: Persisted dashboard/report JSON created by a newer or older version of the app being loaded by a version without that summary type; plugin or API code constructing SummaryContent by hand with an invalid type; a rename of the type union not migrated in stored configs.
Related errors
- Error loading data into the spreadsheet.
- Invalid start date format
- Invalid end date format
- Invalid date format provided
- Invalid date values provided
AI-assisted analysis of actualbudget/actual@d4334cb6e6 (2026-08-29).
Data as JSON: /api/errors/3ab61e71cc374b36.
Report an issue: GitHub.