actualbudget/actual · error · APIError
Account group name is required
Error message
Account group name is required
What it means
api.accountGroupUpdate() converts the provided fields via the account-group model's fromExternal() and requires a group name. If the resulting group.name is null/undefined (i.e. no name field was supplied), the update would blank or invalidate the group, so the API throws this APIError.
Source
Thrown at packages/loot-core/src/server/api.ts:692
handlers['api/account-groups-get'] = async function () {
checkFileOpen();
const groups = await handlers['account-groups-get']();
return groups.map(group => accountGroupModel.toExternal(group));
};
handlers['api/account-group-create'] = withMutation(async function ({ group }) {
checkFileOpen();
return handlers['account-group-create']({ name: group.name });
});
handlers['api/account-group-update'] = withMutation(async function ({
id,
fields,
}) {
checkFileOpen();
const group = accountGroupModel.fromExternal(fields);
if (group.name == null) {
throw APIError('Account group name is required');
}
return handlers['account-group-update']({ id, name: group.name });
});
handlers['api/account-group-delete'] = withMutation(async function ({ id }) {
checkFileOpen();
await handlers['account-group-delete']({ id });
});
handlers['api/categories-get'] = async function ({
hidden,
}: { hidden?: boolean } = {}) {
checkFileOpen();
const result = await handlers['get-categories']({ hidden });
return result.list.map(category => categoryModel.toExternal(category));
};
handlers['api/category-groups-get'] = async function ({View on GitHub (pinned to d4334cb6e6)
Solutions
- Always include a non-null name in the fields object (use the current group's name if only toggling other attributes)
- Fetch the group first and spread it: api.accountGroupUpdate(id, { ...existing, name: existing.name })
- Validate fields.name is a non-empty string before calling
Example fix
// before
await api.accountGroupUpdate(id, { cash: 1000 });
// after
const group = await api.accountGroupGet(id);
await api.accountGroupUpdate(id, { ...group, cash: 1000, name: group.name }); Defensive patterns
Strategy: validation
Validate before calling
const group = accountGroupModel.fromExternal(fields);
if (group.name == null) throw APIError('Account group name is required'); Type guard
function hasValidName(g) {
return g.name != null && String(g.name).length > 0;
} Try / catch
try {
await updateAccountGroup(args);
} catch (e) {
if (/name is required/.test(e.message)) {
throw new UserInputError('name is required for account groups');
}
throw e;
} Prevention
- Make name mandatory in the external input schema (zod/JSON schema)
- Require full-group payloads for updates
- Reject empty names at the boundary
When it happens
Trigger: Calling api.accountGroupUpdate(id, fields) where fields omits 'name' or passes name: null/undefined.
Common situations: Partially-patch-style updates where the caller assumes only changed fields are needed; forms that submit empty names; destructuring/serialization dropping the name key.
Understand the failure class
Background: "Missing required field" and "field is required" errors: why libraries reject payloads that omit mandatory fields — this error's family across 20 libraries.
Related errors
- Unknown payee name normalization: ${String(normalization)}
- `date` is required when adding a transaction
- Amount is invalid, must be an integer: ${trans.amount}
- "${field}" is required for table "${table}": ${JSON.stringif
- There is already a filter named ${item.name}
AI-assisted analysis of actualbudget/actual@d4334cb6e6 (2026-08-29).
Data as JSON: /api/errors/7abc9b75701b3851.
Report an issue: GitHub.