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

  1. Verify the computed amount is > 0 before calling; skip the hold when there is nothing left
  2. Check sign conventions — you may need to negate a 'leftover' value or use a different API (reset/cover) for negative balances
  3. 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

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


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