actualbudget/actual · error · CompileError
Invalid internal table filter: field names cannot contain pa
Error message
Invalid internal table filter: field names cannot contain paths
What it means
Internal table filters must reference plain columns of the internal table only. Because these filters are compiled without join support, a filter key containing a dot (a path into a related table, e.g. `payee.name`) cannot be resolved and CompileError is thrown.
Source
Thrown at packages/loot-core/src/server/aql/compiler.ts:1099
const { withDead, validateRefs = true, tableOptions, rawMode } = queryState;
const {
tableViews = {},
tableFilters = () => [],
customizeQuery = queryState => queryState,
} = schemaConfig;
const internalTableFilters = name => {
const filters = tableFilters(name);
// These filters cannot join tables and must be simple strings
for (const filter of filters) {
if (Array.isArray(filter)) {
throw new CompileError(
'Invalid internal table filter: only object filters are supported',
);
}
if (Object.keys(filter)[0].indexOf('.') !== -1) {
throw new CompileError(
'Invalid internal table filter: field names cannot contain paths',
);
}
}
return filters;
};
const tableRef = (name: string, isJoin?: boolean) => {
const view =
typeof tableViews === 'function'
? tableViews(name, { withDead, isJoin, tableOptions })
: tableViews[name];
return view || name;
};
const tableName = queryState.table;
const {View on GitHub (pinned to d4334cb6e6)
Solutions
- Flatten the filter to a direct column of the internal table (e.g. `payee` id instead of `payee.name`).
- Perform the path-based constraint in the main query conditions rather than in tableFilters.
- Denormalize the needed value onto the internal table at write time if the constraint is always required.
Example fix
// before
{ 'account.name': 'Checking' }
// after
{ account: checkingAccountId } Defensive patterns
Strategy: validation
Validate before calling
function assertNoPathFilters(filters) {
for (const f of filters) {
for (const key of Object.keys(f)) {
if (key.includes('.')) throw new Error(`Internal table filter key cannot contain a path: ${key}`);
}
}
} Type guard
const isPlainColumnFilter = (f) => typeof f === 'object' && f !== null && !Array.isArray(f) && Object.keys(f).every(k => !k.includes('.')); Prevention
- Filter internal tables only by their own columns.
- Move related-table constraints into the query's filter clause.
- Reject dotted keys when building filters programmatically.
When it happens
Trigger: Registering an internal table filter like `{'payee.name': 'foo'}` in the tableFilters mapping for an internal table, or programmatically building nested-path filter keys.
Common situations: Trying to constrain internal tables by related-table fields, or copying filter objects built for normal queries (which allow paths) into tableFilters.
Related errors
- Invalid internal table filter: only object filters are suppo
- Table "${tableName}" does not exist in the schema
- Field "${field}" does not exist in table "${tableName}"
- Path error: ${tableName} table does not exist
- Table "${pathInfo.tableName}" does not exist
AI-assisted analysis of actualbudget/actual@d4334cb6e6 (2026-08-29).
Data as JSON: /api/errors/64f96c6b043b71a3.
Report an issue: GitHub.