actualbudget/actual · critical

Table "${table}" does not exist

Error message

Table "${table}" does not exist

What it means

conform validates that the table name passed to an insert/update/query exists in the aql schema map before touching fields. An unknown table name means a typo or an attempt to query a table this schema version does not know about, so it throws 'Table "X" does not exist'.

Source

Thrown at packages/loot-core/src/server/aql/schema-helpers.ts:97

      } catch {
        return type === 'json/fallback' ? value : null;
      }
    default:
  }

  return value;
}

export function conform(
  schema,
  schemaConfig,
  table,
  obj,
  { skipNull = false } = {},
) {
  const tableSchema = schema[table];
  if (tableSchema == null) {
    throw new Error(`Table "${table}" does not exist`);
  }

  const views = schemaConfig.views || {};

  // Rename fields if necessary
  const fieldRef = field => {
    if (views[table] && views[table].fields) {
      return views[table].fields[field] || field;
    }
    return field;
  };

  return Object.fromEntries(
    Object.keys(obj)
      .map(field => {
        // Fields that start with an underscore are ignored
        if (field[0] === '_') {
          return null;

View on GitHub (pinned to d4334cb6e6)

Solutions

  1. Check the spelling of the table name against the schema in packages/loot-core/src/server/aql/schema (e.g. 'transactions', 'accounts', 'payees').
  2. Update the code to the current table name if the schema was renamed in a newer Actual version.
  3. If adding a new table, register it in the aql schema map before using conform.
  4. Validate the table name comes from a trusted constant, not user input.

Example fix

// before
convertForInsert(schema, schemaConfig, 'transcations', obj);
// after
convertForInsert(schema, schemaConfig, 'transactions', obj);
Defensive patterns

Strategy: validation

Validate before calling

const KNOWN_TABLES = new Set(['transactions','accounts','payees','category_groups','categories']);
if (!KNOWN_TABLES.has(table)) throw new Error(`Unknown table: ${table}`);

Try / catch

try {
  return convertForInsert(schema, schemaConfig, table, obj);
} catch (e) {
  if (e.message.includes('does not exist')) {
    logger.error('Unknown table in insert', { table });
    throw new Error(`Internal error: invalid table ${table}`);
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling convertForInsert/convertForUpdate (or anything using conform, like `obj`) with a table name that is misspelled, deprecated, or simply not present in the schema registry passed in.

Common situations: Custom scripts/plugins referencing internal tables renamed between Actual versions, typos like 'transactions ' (trailing space) or 'transcations', and code written against a fork whose schema diverged.

Related errors


AI-assisted analysis of actualbudget/actual@d4334cb6e6 (2026-08-29). Data as JSON: /api/errors/8648163cbd90ec60. Report an issue: GitHub.