actualbudget/actual · error
Conditions are required
Error message
Conditions are required
What it means
createFilter requires at least one condition. If filter.state.conditions is an empty array (length 0), the else branch throws 'Conditions are required'. A saved filter with no conditions would match nothing and is considered invalid.
Source
Thrown at packages/loot-core/src/server/filters/app.ts:138
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;
}
async function updateFilter(filter) {
const item = {
id: filter.state.id,
conditions: filter.state.conditions,
conditionsOp: filter.state.conditionsOp,
name: filter.state.name,
};
if (item.name) {
if (await filterNameExists(item.name, item.id, false)) {
throw new Error('There is already a filter named ' + item.name);View on GitHub (pinned to d4334cb6e6)
Solutions
- Ensure state.conditions contains at least one condition object ({field, op, value, options}) before calling createFilter.
- Validate conditions.length > 0 client-side and disable save until a condition is added.
- Catch the error and surface 'add a condition' guidance to the user.
Example fix
// before
await aql.query('filter-create', { state: { name: 'My filter', conditions: [], conditionsOp: 'and' } });
// after
const conditions = [{ field: 'amount', op: 'gt', value: 100, options: [] }];
if (conditions.length === 0) throw new Error('Add at least one condition');
await aql.query('filter-create', { state: { name: 'My filter', conditions, conditionsOp: 'and' } }); Defensive patterns
Strategy: validation
Validate before calling
if (!Array.isArray(state.conditions) || state.conditions.length === 0) {
throw new Error('At least one condition is required');
} Type guard
function hasConditions(state: { conditions?: unknown[] }): state is { conditions: [unknown, ...unknown[]] } {
return Array.isArray(state.conditions) && state.conditions.length > 0;
} Try / catch
try {
await aql.query('filter-create', { state });
} catch (e) {
if (e.message === 'Conditions are required') {
// guide the user to add a condition
} else throw e;
} Prevention
- Require at least one condition row before enabling save
- In scripts, never pass conditions: [] as a placeholder
- Validate condition objects have field/op/value set
When it happens
Trigger: Calling filter-create with state.conditions = []; a UI allowing the save button while the condition builder is empty; a script constructing a filter payload with an unpopulated conditions array.
Common situations: Custom frontends on the Actual API that don't enforce at least one rule row; bulk-import tooling writing filters with placeholder empty conditions; race where conditions are cleared before submit.
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
- There is already a filter named ${item.name}
- Filter name is required
- Unknown payee name normalization: ${String(normalization)}
- `date` is required when adding a transaction
- Amount is invalid, must be an integer: ${trans.amount}
AI-assisted analysis of actualbudget/actual@d4334cb6e6 (2026-08-29).
Data as JSON: /api/errors/670d4a9c2d6707d3.
Report an issue: GitHub.