actualbudget/actual · error · Error

Unknown table "${table}". Available tables: ${AVAILABLE_TABL

Error message

Unknown table "${table}". Available tables: ${AVAILABLE_TABLES}

What it means

After resolving the table name, `buildQueryFromFlags` validates it against `TABLE_SCHEMA`. A table name that is not a known key throws this error, listing all available tables, because the query layer cannot generate expressions for an unknown table.

Source

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

    if (cmdOpts.table && cmdOpts.table !== 'transactions') {
      throw new Error(
        '--last implies --table transactions. Cannot use with --table ' +
          cmdOpts.table,
      );
    }
    if (cmdOpts.limit) {
      throw new Error('--last and --limit are mutually exclusive');
    }
  }

  const table =
    cmdOpts.table ?? (last !== undefined ? 'transactions' : undefined);
  if (!table) {
    throw new Error('--table is required (or use --file or --last)');
  }

  if (!(table in TABLE_SCHEMA)) {
    throw new Error(
      `Unknown table "${table}". Available tables: ${AVAILABLE_TABLES}`,
    );
  }

  if (cmdOpts.where && cmdOpts.filter) {
    throw new Error('--where and --filter are mutually exclusive');
  }

  if (cmdOpts.count && cmdOpts.select) {
    throw new Error('--count and --select are mutually exclusive');
  }

  let queryObj = api.q(table);

  if (cmdOpts.count) {
    queryObj = queryObj.calculate({ $count: '*' });
  } else if (cmdOpts.select) {
    queryObj = queryObj.select(cmdOpts.select.split(','));

View on GitHub (pinned to d4334cb6e6)

Solutions

  1. Use one of the tables listed in the error message exactly (e.g. `transactions`, not `transaction`).
  2. Check casing — table keys are matched exactly, not case-insensitively.
  3. Run the command with a deliberately bad table name once to see the full list of `AVAILABLE_TABLES`, or inspect `TABLE_SCHEMA` in packages/cli/src/commands/query.ts.

Example fix

// before
actual query --table transaction --last 10
// after
actual query --table transactions --last 10
Defensive patterns

Strategy: validation

Validate before calling

const AVAILABLE = ['transactions','accounts','categories','payees'];
if (!AVAILABLE.includes(table)) {
  throw new Error(`unknown table "${table}"; expected one of ${AVAILABLE.join(', ')}`);
}

Try / catch

try {
  await cli(['query', '--table', table, ...rest]);
} catch (e) {
  if (e.message.startsWith('Unknown table')) {
    console.error(e.message); // lists the available tables
  }
}

Prevention

When it happens

Trigger: Passing a misspelled or pluralization-wrong table, e.g. `--table transaction`, `--table Transaction`, `--table category`, or any name not present in `TABLE_SCHEMA`.

Common situations: Typos and case-sensitivity mistakes when hand-typing; assuming REST-ish plural names; copying table names from other budgeting tools.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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