actualbudget/actual · error · APIError
Amount to hold needs to be greater than 0
Error message
Amount to hold needs to be greater than 0
What it means
api.holdForNextMonth() carries leftover budgeted money for a category into the next month. A hold only makes sense for a positive amount, so the handler rejects amount <= 0 with this APIError before delegating to the internal budget handler.
Source
Thrown at packages/loot-core/src/server/api.ts:503
}) {
checkFileOpen();
await validateMonth(month);
await validateExpenseCategory('budget-set-carryover', categoryId);
return handlers['budget/set-carryover']({
startMonth: month,
category: categoryId,
flag,
});
});
handlers['api/budget-hold-for-next-month'] = withMutation(async function ({
month,
amount,
}) {
checkFileOpen();
await validateMonth(month);
if (amount <= 0) {
throw APIError('Amount to hold needs to be greater than 0');
}
return handlers['budget/hold-for-next-month']({
month,
amount,
});
});
handlers['api/budget-reset-hold'] = withMutation(async function ({ month }) {
checkFileOpen();
await validateMonth(month);
return handlers['budget/reset-hold']({ month });
});
handlers['api/transactions-export'] = async function ({
transactions,
categoryGroups,
payees,
accounts,View on GitHub (pinned to d4334cb6e6)
Solutions
- Verify the computed amount is > 0 before calling; skip the hold when there is nothing left
- Check sign conventions — you may need to negate a 'leftover' value or use a different API (reset/cover) for negative balances
- Log the raw amount and its source to find where the 0/negative value originates
Example fix
// before
const leftover = endBalance - reserve;
await api.holdForNextMonth(month, categoryId, leftover);
// after
const leftover = endBalance - reserve;
if (leftover > 0) {
await api.holdForNextMonth(month, categoryId, leftover);
} Defensive patterns
Strategy: validation
Validate before calling
if (!(typeof amount === 'number' && amount > 0)) throw APIError('Amount to hold needs to be greater than 0'); Type guard
function isPositive(n) {
return typeof n === 'number' && Number.isFinite(n) && n > 0;
} Try / catch
try {
await holdForNextMonth(args);
} catch (e) {
if (/greater than 0/.test(e.message)) return null;
throw e;
} Prevention
- Clamp computed hold amounts to a minimum of 0 and skip when 0
- Sanitize numeric inputs from external sources
- Document the positivity requirement in the API surface
When it happens
Trigger: Calling api.holdForNextMonth({ month, categoryId, amount }) with amount = 0, a negative number, or a non-numeric value coerced to <= 0 (e.g. NaN fails the <= 0 check? NaN comparison is false, but 0 or negative passes validation fail here).
Common situations: Scripts computing a hold from a balance that ended up 0 or negative after overspending; passing an uninitialized variable; unit conversion mistakes (cents vs dollars rounding to 0).
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Error importing budget: ${result.error}
- Error importing budget: no budget was loaded
- Error exporting budget: ${result.error}
- Error exporting budget: no data was returned
- Invalid BUDGET_QUERY dimension: ${dimension}
AI-assisted analysis of actualbudget/actual@d4334cb6e6 (2026-08-29).
Data as JSON: /api/errors/06254c93c8de2e9e.
Report an issue: GitHub.