actualbudget/actual · error · Error

Unknown table "${table}". Available tables: ${Object.keys(TA

Error message

Unknown table "${table}". Available tables: ${Object.keys(TABLE_SCHEMA).join(', ')}

What it means

The `actual fields <table>` command looks up the requested table in the CLI's built-in TABLE_SCHEMA (transactions, accounts, categories, payees, rules, schedules). If the table name is not one of these keys, it throws with the list of valid tables. The schema is hardcoded in the CLI, so only these tables are known.

Source

Thrown at packages/cli/src/commands/query.ts:347

    });

  query
    .command('tables')
    .description('List available tables for querying')
    .action(() => {
      const opts = program.opts();
      const tables = Object.keys(TABLE_SCHEMA).map(name => ({ name }));
      printOutput(tables, opts.format);
    });

  query
    .command('fields <table>')
    .description('List fields for a given table')
    .action((table: string) => {
      const opts = program.opts();
      const schema = TABLE_SCHEMA[table];
      if (!schema) {
        throw new Error(
          `Unknown table "${table}". Available tables: ${Object.keys(TABLE_SCHEMA).join(', ')}`,
        );
      }
      const fields = Object.entries(schema).map(([name, info]) => ({
        name,
        type: info.type,
        ...(info.ref ? { ref: info.ref } : {}),
      }));
      printOutput(fields, opts.format);
    });
}

View on GitHub (pinned to d4334cb6e6)

Solutions

  1. Use one of the listed tables exactly: transactions, accounts, categories, payees, rules, schedules
  2. Fix case: all table names are lowercase (e.g. `payees`, not `Payees`)
  3. For tables missing from the schema (e.g. category_groups), query them via `actual query <table>` directly against the API or use dotted refs like category.name
  4. File an issue to extend TABLE_SCHEMA if the table should be supported

Example fix

// before
actual fields transaction

// after
actual fields transactions
Defensive patterns

Strategy: validation

Validate before calling

const KNOWN_TABLES = ['transactions','accounts','categories','payees','rules','schedules'];
if (!KNOWN_TABLES.includes(table)) {
  throw new Error(`Table "${table}" not supported by 'actual fields'; use one of: ${KNOWN_TABLES.join(', ')}`);
}

Type guard

function isKnownTable(t: string): t is 'transactions'|'accounts'|'categories'|'payees'|'rules'|'schedules' {
  return ['transactions','accounts','categories','payees','rules','schedules'].includes(t);
}

Try / catch

try {
  const out = await run(['actual', 'fields', table]);
} catch (e) {
  if (String(e.message).startsWith('Unknown table')) {
    console.error(`"${table}" is not in the CLI schema; run 'actual fields transactions' to see the format`);
  } else throw e;
}

Prevention

When it happens

Trigger: `actual fields transaction` (singular instead of plural); `actual fields Transactions` (case-sensitive lookup); `actual fields category_groups` or `actual fields schedules_new` — tables that exist in the underlying data but are absent from the CLI schema.

Common situations: Typos and singular/plural confusion; expecting every loot-core table (schedules, category_groups, messages, etc.) to be listed; case-insensitivity assumptions from other CLIs.

Related errors


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