actualbudget/actual · error

Invalid limit period. Check template syntax

Error message

Invalid limit period. Check template syntax

What it means

The limit's `period` keyword must be one of daily, weekly, or monthly. When `checkLimit` (constructor) finds a period value it does not recognize, it throws, indicating the template line is malformed.

Source

Thrown at packages/loot-core/src/server/budget/category-template-context.ts:621

        const nextMonth = monthUtils.nextMonth(this.month);
        let week = limitDef.start;
        const baseLimit = amountToInteger(
          limitDef.amount,
          this.currency.decimalPlaces,
        );
        while (week < nextMonth) {
          if (week >= this.month) {
            this.limitAmount += baseLimit;
          }
          week = monthUtils.addWeeks(week, 1);
        }
      } else if (limitDef.period === 'monthly') {
        this.limitAmount = amountToInteger(
          limitDef.amount,
          this.currency.decimalPlaces,
        );
      } else {
        throw new Error('Invalid limit period. Check template syntax');
      }

      //amount is good save the rest
      this.limitCheck = true;
      this.limitHold = limitDef.hold ? true : false;
      // check if the limit is already met and save the excess
      if (this.fromLastMonth >= this.limitAmount) {
        this.limitMet = true;
        if (this.limitHold) {
          this.limitExcess = 0;
          this.toBudgetAmount = 0;
          this.fullAmount = 0;
        } else {
          this.limitExcess = this.fromLastMonth - this.limitAmount;
          this.toBudgetAmount = -this.limitExcess;
          this.fullAmount = -this.limitExcess;
        }
      }

View on GitHub (pinned to d4334cb6e6)

Solutions

  1. Fix the period keyword to exactly one of `daily`, `weekly`, or `monthly`
  2. If you need yearly behavior, express it with monthly amounts or a repeating `by` template instead

Example fix

// before
#template up to 1200 yearly
// after
#template up to 100 monthly
Defensive patterns

Strategy: validation

Validate before calling

const PERIODS = ['daily','weekly','monthly'];
if (!PERIODS.includes(limitDef.period)) throw new Error(`invalid limit period: ${limitDef.period}`);

Type guard

function isValidPeriod(p) {
  return p === 'daily' || p === 'weekly' || p === 'monthly';
}

Try / catch

try {
  await init();
} catch (e) {
  if (e.message.includes('Invalid limit period')) {
    // correct the period keyword to daily/weekly/monthly
  } else throw e;
}

Prevention

When it happens

Trigger: A `up to` template specifies a period other than daily/weekly/monthly — e.g. a typo like `#template up to 100 weekley`, `yearly`, or an empty/garbled period token parsed into `limitDef.period`.

Common situations: Typo in the period keyword; using a period the goal-template grammar does not support (e.g. yearly/annually); template string mangled by note editing.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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