actualbudget/actual · error
Target month has passed, remove or update the target month
Error message
Target month has passed, remove or update the target month
What it means
A `by` template targets a month that is already in the past, and the template is not repeating. The engine throws because the target can never be reached and the template would have no effect.
Source
Thrown at packages/loot-core/src/server/budget/category-template-context.ts:530
.filter(t => t.type === 'schedule' || t.type === 'by')
.forEach(t => {
if (t.priority !== lowestPriority) {
throw new Error(
`Schedule and By templates must be the same priority level. Fix by setting all Schedule and By templates to priority level ${lowestPriority}`,
);
//t.priority = lowestPriority;
}
});
// check if the target date is past and not repeating
templates
.filter(t => t.type === 'by' || t.type === 'spend')
.forEach(t => {
const range = monthUtils.differenceInCalendarMonths(
`${t.month}`,
month,
);
if (range < 0 && !(t.repeat || t.annual)) {
throw new Error(
`Target month has passed, remove or update the target month`,
);
}
});
}
static async checkPercentage(templates: Template[]) {
const pt = templates.filter(t => t.type === 'percentage');
if (pt.length === 0) return;
const availCategories = await db.getCategories();
const incomeCategories = availCategories.filter(c => c.is_income);
const availNames = new Set(
incomeCategories.map(c => c.name.toLocaleLowerCase()),
);
const availIds = new Set(incomeCategories.map(c => c.id));
const specialSources = new Set(['all income', 'available funds']);View on GitHub (pinned to d4334cb6e6)
Solutions
- Update the target month in the template to a current or future month
- Add `repeat each` or make it an `annual` template if the goal should recur
- Remove the outdated `#template by ...` line if the goal is complete
Example fix
// before #template by 2024-06 // after #template by 2027-01
Defensive patterns
Strategy: validation
Validate before calling
const target = '2024-06';
const diff = monthUtils.differenceInCalendarMonths(target, monthUtils.currentMonth());
if (diff < 0) throw new Error(`by-target ${target} is in the past; add repeat/annual or update the month`); Type guard
function isReachingableTarget(t, month) {
return monthUtils.differenceInCalendarMonths(String(t.month), month) >= 0 || Boolean(t.repeat) || Boolean(t.annual);
} Try / catch
try {
await init();
} catch (e) {
if (e.message.includes('Target month has passed')) {
// update the by-month, add repeat/annual, or delete the line
} else throw e;
} Prevention
- Audit `#template by` lines at the start of each year
- Use `repeat each` or `annual` for recurring goals
- Remove templates once their savings target is met
When it happens
Trigger: `checkByAndScheduleAndSpend` (init) computes `differenceInCalendarMonths(t.month, currentMonth) < 0` for a template where neither `repeat` nor `annual` is set — e.g. `#template by 2024-06` evaluated in a later month.
Common situations: Leaving an old one-time savings-goal template in place after its target date passed; template notes copied from an old budget; annual goals mistakenly written without the `annual`/`repeat` keyword.
Related errors
- Invalid cutoff date: expected a valid date (e.g. YYYY-MM-DD)
- Invalid date:
- Schedule ${t.name.trim()} does not exist
- Schedule and By templates must be the same priority level. F
- Category "${raw}" is not found in available income categorie
AI-assisted analysis of actualbudget/actual@d4334cb6e6 (2026-08-29).
Data as JSON: /api/errors/299a0e0d280ed688.
Report an issue: GitHub.