actualbudget/actual · error

An error occurred while parsing the template

Error message

An error occurred while parsing the template

What it means

getInitialState switches on template.type; the 'error' type is what the template parser produces when category notes could not be parsed into a valid template. Encountering it here means an unparsed/error template reached the state-initialization path, so it throws a generic parse-failure message.

Source

Thrown at packages/desktop-client/src/components/budget/goals/reducer.ts:86

      };
    case 'refill':
      return {
        template,
        displayType: 'refill',
      };
    case 'average':
    case 'copy':
      return {
        template,
        displayType: 'historical',
      };
    case 'goal':
      return {
        template,
        displayType: 'goal',
      };
    case 'error':
      throw new Error('An error occurred while parsing the template');
    default:
      throw new Error(
        `Unknown template type: ${String(type satisfies undefined)}`,
      );
  }
};

const changeType = (
  prevState: ReducerState,
  visualType: DisplayTemplateType,
): ReducerState => {
  switch (visualType) {
    case 'limit':
      if (prevState.template.type === 'limit') {
        return prevState;
      }
      return {
        displayType: visualType,

View on GitHub (pinned to d4334cb6e6)

Solutions

  1. Fix the template syntax in the category notes so the parser produces a valid template type
  2. Check the parse output for a parse error message and correct the offending directive
  3. If this should be handled gracefully, check for type === 'error' before calling getInitialState and show a user-facing parse error instead

Example fix

// before
dispatch({ type: 'set-template', payload: parseTemplate(notes) });
// after
const parsed = parseTemplate(notes);
if (parsed.type === 'error') {
  notify('The template in the category notes could not be parsed.');
  return;
}
dispatch({ type: 'set-template', payload: parsed });
Defensive patterns

Strategy: validation

Validate before calling

const parsed = parseTemplate(notes);
if (parsed.type === 'error') {
  notify('Category notes contain an invalid template.');
  return;
}
dispatch({ type: 'set-template', payload: parsed });

Type guard

const isParsedTemplate = (t: Template): t is Exclude<Template, { type: 'error' }> =>
  t.type !== 'error';

Try / catch

try {
  dispatch({ type: 'set-template', payload: template });
} catch (e) {
  if (e instanceof Error && e.message.includes('parsing the template')) {
    notify('Fix the #template syntax in the category notes.');
  } else throw e;
}

Prevention

When it happens

Trigger: Dispatching 'set-template' (or triggering mapTemplateTypesForUpdate merge) with a Template whose type is 'error' — i.e. the notes parser failed (bad template syntax like #template with invalid arguments) and the error object was passed on.

Common situations: Malformed template directives in category notes (e.g. #template up to with a bad amount or unsupported syntax); user edited notes by hand producing invalid template text; parser version differences after upgrades.

Related errors


AI-assisted analysis of actualbudget/actual@d4334cb6e6 (2026-08-29). Data as JSON: /api/errors/277fb79e689dd461. Report an issue: GitHub.