actualbudget/actual · error

Invalid adjustment percentage (${parsedTemplate.adjustment}%

Error message

Invalid adjustment percentage (${parsedTemplate.adjustment}%). Must be between -100% and 1000%

What it means

Actual Budget's budget templates (the `#template` directives in category notes) support an `adjust` directive that can take a percentage. When the template is parsed during `getCategoriesWithTemplates`, the parsed adjustment value is validated: percentages are rejected if they are <= -100 (which would zero out or invert the category budget incoherently) or > 1000 (an implausible multiplier). The library throws this error to surface a malformed template directive in a category's notes rather than silently producing a wrong budget amount.

Source

Thrown at packages/loot-core/src/server/budget/template-notes.ts:122

      const description =
        descriptionLines.length > 0 ? descriptionLines.join('\n') : undefined;
      descriptionLines = [];

      try {
        const parsedTemplate: Template = parse(trimmedLine);

        // Validate schedule adjustments
        if (
          (parsedTemplate.type === 'average' ||
            parsedTemplate.type === 'schedule') &&
          parsedTemplate.adjustment !== undefined
        ) {
          if (parsedTemplate.adjustmentType === 'percent') {
            if (
              parsedTemplate.adjustment <= -100 ||
              parsedTemplate.adjustment > 1000
            ) {
              throw new Error(
                `Invalid adjustment percentage (${parsedTemplate.adjustment}%). Must be between -100% and 1000%`,
              );
            }
          } else if (parsedTemplate.adjustmentType === 'fixed') {
            //placeholder for potential validation of amount/fixed adjustments
          }
        }

        parsedTemplates.push(
          description ? { ...parsedTemplate, description } : parsedTemplate,
        );
      } catch (e: unknown) {
        const errorTemplate: Template = {
          type: 'error',
          directive: 'error',
          line,
          error: (e as Error).message,
        };

View on GitHub (pinned to d4334cb6e6)

Solutions

  1. Open the category notes in the affected budget and fix the `#template adjust` directive so its percentage is in the valid range (-100% < p <= 1000%, exclusive of -100, inclusive of 1000).
  2. If you only need to drop a category's budget to zero, use `#template 0` or a fixed-amount adjust rather than `adjust -100%`.
  3. If the bad note came from a sync/restore, correct the note on the source device or delete the directive before re-syncing.
  4. Wrap the template-reading call in a try/catch during migration/import scripts so one bad note can be reported to the user with the category name instead of aborting the whole operation.

Example fix

// before (category note)
#template adjust -100%

// after
#template adjust -50%
Defensive patterns

Strategy: validation

Validate before calling

function isValidAdjustPercent(pct) {
  return typeof pct === 'number' && Number.isFinite(pct) && pct > -100 && pct <= 1000;
}
// scan category notes before syncing/importing:
// for each note, extract /#template\s+adjust\s+(-?[\d.]+)%/ and assert isValidAdjustPercent(parseFloat(m[1]))

Type guard

function isWithinAdjustRange(value) {
  return typeof value === 'number' && Number.isFinite(value) && value > -100 && value <= 1000;
}

Prevention

When it happens

Trigger: Calling `getCategoriesWithTemplates` (directly or via `categoriesWithTemplates`/`categoryWithTemplates`) while one or more category notes contain a template directive like `#template adjust 2000%` (above 1000) or `#template adjust -150%` (at or below -100). Any budget action that reads templates with such a note triggers the throw.

Common situations: A user hand-edits category notes and typos an extra zero (e.g. `10000%` instead of `1000%`); a synced budget imported from another device contains a directive written before validation existed; a template-sharing workflow copies an extreme directive between budgets; a user misunderstands the allowed range and tries `-100%` expecting 'remove all budgeted amount'.

Related errors


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