actualbudget/actual · error · CompileError
Table "${tableName}" does not exist in the schema
Error message
Table "${tableName}" does not exist in the schema What it means
Actual's AQL query compiler resolves every table referenced in a query against the supplied schema catalog. getFieldDescription looks up schema[tableName]; when the table is absent from the schema object it throws CompileError with this message. This guards against querying tables that don't exist (or aren't exposed to AQL) before any SQL is generated.
Source
Thrown at packages/loot-core/src/server/aql/compiler.ts:59
const parts = path.split('.');
return { path: parts.slice(0, -1).join('.'), field: parts[parts.length - 1] };
}
function isKeyword(str) {
return str === 'group';
}
export function quoteAlias(alias) {
return alias.indexOf('.') === -1 && !isKeyword(alias) ? alias : `"${alias}"`;
}
function typed(value, type, { literal = false } = {}) {
return { value, type, literal };
}
function getFieldDescription(schema, tableName, field) {
if (schema[tableName] == null) {
throw new CompileError(`Table "${tableName}" does not exist in the schema`);
}
const fieldDesc = schema[tableName][field];
if (fieldDesc == null) {
throw new CompileError(
`Field "${field}" does not exist in table "${tableName}"`,
);
}
return fieldDesc;
}
function makePath(state, path) {
const { schema, paths } = state;
const parts = path.split('.');
if (parts.length < 2) {
throw new CompileError('Invalid path: ' + path);
}View on GitHub (pinned to d4334cb6e6)
Solutions
- Correct the table name in the query to one present in the schema (transactions, accounts, payees, categories, category_groups, rules, schedules, etc.).
- Check the schema map in packages/loot-core/src/server/aql/schema.ts for the exact exposed table names.
- If the table was renamed in a newer Actual version, update the query to the new name.
- For dynamic queries, validate the table name against Object.keys(schema) before building the query.
Example fix
// before
const q = aql.query('transations').select('*');
// after
const q = aql.query('transactions').select('*'); Defensive patterns
Strategy: validation
Validate before calling
import { schema } from '../server/aql/schema';
function tableExists(name) {
return Object.prototype.hasOwnProperty.call(schema, name);
}
if (!tableExists(tableName)) throw new Error(`unknown AQL table: ${tableName}`); Type guard
function isAqlTable(name) {
return typeof name === 'string' && name in schema;
} Try / catch
import { CompileError } from '../server/aql/compiler';
try {
const { data } = await aql.runQuery(q);
} catch (e) {
if (e instanceof CompileError && e.message.includes('does not exist in the schema')) {
logger.error({ table: e.message }, 'fix table name in query');
} else throw e;
} Prevention
- Keep a constant/list of valid AQL table names instead of inlining strings.
- Type-check queries with the table-name union type if building queries programmatically.
- Grep packages/loot-core/src/server/aql/schema.ts when unsure of a table's exposed name.
When it happens
Trigger: Running aquery (loot-core's aql.runQuery / Query class) whose from()/table name is misspelled or not part of the schema — e.g. q('transations') instead of q('transactions'), or a custom/internal table name not registered in the schema map passed to the compiler via fieldDesc.
Common situations: Typo in a custom query built with the aql query builder; using an internal-only or deprecated table name after a schema rename between Actual versions; API/plugin code (actual-js) referencing tables the AQL layer doesn't expose; dynamically constructed table names built from user input.
Related errors
- Table "${table}" does not exist
- Unknown table "${table}". Available tables: ${Object.keys(TA
- Field "${field}" does not exist in table "${tableName}"
- Path error: ${tableName} table does not exist
- Can't cast ${expr.type} to date
AI-assisted analysis of actualbudget/actual@d4334cb6e6 (2026-08-29).
Data as JSON: /api/errors/2f4a91c2e8d79319.
Report an issue: GitHub.