actualbudget/actual · critical
Error inserting: table "${table}" does not exist
Error message
Error inserting: table "${table}" does not exist What it means
convertForInsert verifies the target table exists in the schema before iterating its fields to apply defaults. An unknown table during insert throws 'Error inserting: table "X" does not exist' — the insert-specific variant of the conform table check.
Source
Thrown at packages/loot-core/src/server/aql/schema-helpers.ts:156
}
// This option removes null values (see `convertForInsert`)
if (skipNull && obj[field] == null) {
return null;
}
return [fieldRef(field), convertInputType(obj[field], fieldDesc.type)];
})
.filter(Boolean),
);
}
export function convertForInsert(schema, schemaConfig, table, rawObj) {
const obj = { ...rawObj };
const tableSchema = schema[table];
if (tableSchema == null) {
throw new Error(`Error inserting: table "${table}" does not exist`);
}
// Inserting checks all the fields in the table and adds any default
// values necessary
Object.keys(tableSchema).forEach(field => {
const fieldDesc = tableSchema[field];
if (obj[field] == null) {
if (fieldDesc.default !== undefined) {
obj[field] =
typeof fieldDesc.default === 'function'
? fieldDesc.default()
: fieldDesc.default;
} else if (isRequired(field, fieldDesc)) {
// Although this check is also done in `conform`, it only
// checks the fields in `obj`. For insert, we need to do it
// here to check that all required fields in the table exist
throw new Error(View on GitHub (pinned to d4334cb6e6)
Solutions
- Correct the table name to a valid schema table ('transactions', 'accounts', etc.).
- Grep the aql schema file for the exact registered table names.
- If the table is new, add its schema definition before inserting.
- Ensure the `schema` object passed into convertForInsert is the current full schema map, not a partial/stale copy.
Example fix
// before
insertWithSchema('account', obj, {}); // wrong table
// after
insertWithSchema('accounts', obj, {}); Defensive patterns
Strategy: validation
Validate before calling
const VALID_INSERT_TABLES = new Set(Object.keys(schema));
function safeInsert(table, obj) {
if (!VALID_INSERT_TABLES.has(table)) throw new Error(`Unknown insert table: ${table}`);
return insertWithSchema(table, obj, {});
} Try / catch
try {
return insertWithSchema(table, obj, {});
} catch (e) {
if (e.message.includes('Error inserting: table')) {
logger.error('Insert against unknown table', { table });
return null;
}
throw e;
} Prevention
- Keep table names in a single constants module
- Run integration tests for insert paths after schema upgrades
- Avoid hand-writing table names in plugin/sync code
When it happens
Trigger: Calling convertForInsert (directly or via insertWithSchema / toDb inside a transactor) with a table name that is misspelled, unregistered, or removed in the current schema version.
Common situations: Plugins/custom sync code written against old internal table names, copy-pasted insert code with a wrong table constant, and migrations that dropped or renamed a table without updating insert call sites.
Related errors
- Table "${table}" does not exist
- Error updating: table "${table}" does not exist
- Table "${tableName}" does not exist in the schema
- Field "${field}" does not exist in table "${tableName}"
- Path error: ${tableName} table does not exist
AI-assisted analysis of actualbudget/actual@d4334cb6e6 (2026-08-29).
Data as JSON: /api/errors/b35a16bf451990b1.
Report an issue: GitHub.