actualbudget/actual · error
Filter name is required
Error message
Filter name is required
What it means
createFilter requires a non-empty filter name. If filter.state.name is falsy (empty string, null, undefined), the guard `if (item.name)` fails and the code throws 'Filter name is required' instead of attempting the duplicate-name check. Saved transaction filters are addressed by name in the UI, so a name is mandatory.
Source
Thrown at packages/loot-core/src/server/filters/app.ts:126
return keys1.every(key => opt1[key] === opt2[key]);
}
async function createFilter(filter): Promise<TransactionFilterEntity['id']> {
const filterId = uuidv4();
const item = {
id: filterId,
conditions: filter.state.conditions,
conditionsOp: filter.state.conditionsOp,
name: filter.state.name,
};
if (item.name) {
if (await filterNameExists(item.name, item.id, true)) {
throw new Error('There is already a filter named ' + item.name);
}
} else {
throw new Error('Filter name is required');
}
if (item.conditions.length > 0) {
const condExists = conditionExists(item, filter.filters, true);
if (condExists) {
throw new Error(
'Duplicate filter warning: conditions already exist. Filter name: ' +
condExists,
);
}
} else {
throw new Error('Conditions are required');
}
// Create the filter here based on the info
await db.insertWithSchema('transaction_filters', filterModel.fromJS(item));
return filterId;View on GitHub (pinned to d4334cb6e6)
Solutions
- Provide a non-empty name in filter.state before calling createFilter.
- Validate the name client-side (trim and check length > 0) and disable submit until valid.
- If the name came from user input, trim it and re-check; whitespace-only strings are still falsy after trim only if you trim yourself.
Example fix
// before
await aql.query('filter-create', { state: { name: '', conditions, conditionsOp: 'and' } });
// after
const name = userInput.trim();
if (!name) throw new Error('Filter name is required');
await aql.query('filter-create', { state: { name, conditions, conditionsOp: 'and' } }); Defensive patterns
Strategy: validation
Validate before calling
const name = (state.name ?? '').trim();
if (!name) throw new Error('Filter name is required before calling filter-create'); Type guard
function hasFilterName(state: { name?: string | null }): state is { name: string } {
return typeof state.name === 'string' && state.name.trim().length > 0;
} Try / catch
try {
await aql.query('filter-create', { state });
} catch (e) {
if (e.message === 'Filter name is required') {
// surface a required-field error to the user
} else throw e;
} Prevention
- Validate name non-empty (after trim) before any filter-create call
- Bind the save button to form validity so an empty name cannot submit
- When building payloads in scripts, always set name explicitly
When it happens
Trigger: Calling the filter-create mutator with state.name === '' or missing; a UI form submitting before the user typed a name; a script/plugin constructing the filter payload programmatically and omitting the name field.
Common situations: Automated budget setup scripts that build filter payloads; custom UIs built on the Actual API forgetting the name field; empty-string names after trimming whitespace in custom frontends.
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
- `date` is required when adding a transaction
- There is already a filter named ${item.name}
- Conditions are required
- --table is required when the input file lacks a "table" fiel
- Unknown payee name normalization: ${String(normalization)}
AI-assisted analysis of actualbudget/actual@d4334cb6e6 (2026-08-29).
Data as JSON: /api/errors/ce359fbfca3bffaf.
Report an issue: GitHub.