actualbudget/actual · warning
Unsupported template type reached migration
Error message
Unsupported template type reached migration
What it means
getDisplayTypeFromTemplate maps stored goal templates to editor display types during migration of templates to budget automations. A template with type 'error' means the goal template parser failed on that directive; these are supposed to be filtered out upstream by hasUnsupportedDirective before migration. This throw surfaces a bug where an error-typed (unparseable) template leaked into the migration path, indicating the upstream filter missed it.
Source
Thrown at packages/desktop-client/src/components/modals/BudgetAutomationsModal/migrateTemplatesToAutomations.ts:41
case 'simple':
return 'fixed';
case 'limit':
return 'limit';
case 'refill':
return 'refill';
case 'average':
case 'copy':
return 'historical';
case 'by':
case 'spend':
return 'by';
case 'remainder':
return 'remainder';
case 'goal':
return 'goal';
case 'error':
// filtered upstream by hasUnsupportedDirective; surface if it ever isn't
throw new Error(`Unsupported template type reached migration`);
default: {
const _exhaustive: never = template;
void _exhaustive;
throw new Error(`Unhandled template type`);
}
}
}
// Fill in scheduleId from name (or refresh a stale name from scheduleId) so
// the editor and engine consistently see both.
function hydrateScheduleTemplate(
template: ScheduleTemplate,
schedules: readonly ScheduleEntity[],
): ScheduleTemplate {
const schedule = template.scheduleId
? schedules.find(s => s.id === template.scheduleId)
: template.name
? schedules.find(s => s.name?.trim() === template.name?.trim())View on GitHub (pinned to d4334cb6e6)
Solutions
- Identify the offending template (its category/note text) and inspect why it parsed as type 'error'.
- Fix or remove the malformed goal template directive in the category notes before migrating.
- Extend hasUnsupportedDirective so error-typed templates are excluded from the migration input.
- Update the parser/migration mapping if a previously supported directive now yields an error template after an upgrade.
Example fix
// before const toMigrate = templates.filter(t => t.directive === 'template'); // after const toMigrate = templates.filter( t => t.directive === 'template' && !hasUnsupportedDirective(t), );
Defensive patterns
Strategy: validation
Validate before calling
const migratable = templates.filter( t => t.directive === 'template' && t.type !== 'error' && hasSupportedType(t), ); migrateTemplatesToAutomations(migratable, ...);
Type guard
function isMigratableTemplate(t: Template): boolean {
return t.type !== 'error' && MIGRATION_SUPPORTED_TYPES.has(t.type);
} Try / catch
try {
migrateTemplatesToAutomations(templates, schedules);
} catch (err) {
if (String(err).includes('Unsupported template type reached migration')) {
notifyUser('Some goal templates could not be migrated and were skipped.');
return;
}
throw err;
} Prevention
- Always run hasUnsupportedDirective over the template list before migration.
- Fix or drop templates with type 'error' (unparseable directives) instead of migrating them.
- After parser changes, re-validate previously stored goal templates.
- Report skipped templates to the user rather than failing the whole migration.
When it happens
Trigger: Running migrateTemplatesToAutomations on a budget whose template list still contains templates with `type: 'error'` because hasUnsupportedDirective did not exclude them — e.g. a directive that fails parsing into a supported automation, or a change in the parser producing error templates for previously valid directives.
Common situations: Budgets authored with goal templates that no longer parse after an upgrade; edits to template syntax (renamed/removed directive parameters) leaving error placeholders in notes; the upstream filter's predicate diverging from this switch's cases.
Related errors
- An error occurred while parsing the template
- Unhandled template type
- Unknown display type: ${String(displayType)}
- Template cannot be null
- Unknown template type: ${String(type satisfies undefined)}
AI-assisted analysis of actualbudget/actual@d4334cb6e6 (2026-08-29).
Data as JSON: /api/errors/4e85fde9bb7238f4.
Report an issue: GitHub.