actualbudget/actual · error · Error

--table is required when the input file lacks a "table" fiel

Error message

--table is required when the input file lacks a "table" field

What it means

When `query` reads its query from a `--file`, the JSON may declare which table to query via a top-level `"table"` field. If the file lacks it and no `--table` fallback flag was given, `buildQueryFromFile` cannot determine the data source and throws this error.

Source

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

const AVAILABLE_TABLES = Object.keys(TABLE_SCHEMA).join(', ');

const LAST_DEFAULT_SELECT = [
  'date',
  'account.name',
  'payee.name',
  'category.name',
  'amount',
  'notes',
];

function buildQueryFromFile(
  parsed: Record<string, unknown>,
  fallbackTable: string | undefined,
) {
  const table = typeof parsed.table === 'string' ? parsed.table : fallbackTable;
  if (!table) {
    throw new Error(
      '--table is required when the input file lacks a "table" field',
    );
  }
  let queryObj = api.q(table);
  if (Array.isArray(parsed.select)) queryObj = queryObj.select(parsed.select);
  if (isRecord(parsed.filter)) queryObj = queryObj.filter(parsed.filter);
  if (Array.isArray(parsed.orderBy)) {
    queryObj = queryObj.orderBy(parsed.orderBy);
  }
  if (typeof parsed.limit === 'number') queryObj = queryObj.limit(parsed.limit);
  if (typeof parsed.offset === 'number') {
    queryObj = queryObj.offset(parsed.offset);
  }
  if (Array.isArray(parsed.groupBy)) {
    queryObj = queryObj.groupBy(parsed.groupBy);
  }
  return queryObj;
}

View on GitHub (pinned to d4334cb6e6)

Solutions

  1. Add `"table": "transactions"` (or another valid table) to the JSON file.
  2. Or pass `--table transactions` on the command line as the fallback.
  3. Validate the query JSON against the expected shape before invoking the CLI.

Example fix

// before (q.json)
{ "select": ["date", "amount"] }
// after
{ "table": "transactions", "select": ["date", "amount"] }
Defensive patterns

Strategy: validation

Validate before calling

const q = JSON.parse(fs.readFileSync(file, 'utf8'));
if (typeof q.table !== 'string' && !tableFlag) {
  throw new Error('query file must contain a "table" field or pass --table');
}

Type guard

function hasTable(q: unknown): q is { table: string } & Record<string, unknown> {
  return typeof q === 'object' && q !== null && typeof (q as any).table === 'string';
}

Try / catch

try {
  await cli(['query', '--file', file]);
} catch (e) {
  if (e.message.includes('--table is required')) {
    console.error('Add "table" to the query JSON or pass --table');
  }
}

Prevention

When it happens

Trigger: Running `actual query --file q.json` where q.json has `select`/`filter` but no `"table"` key, and the command line omits `--table`.

Common situations: Hand-written query files copied from examples that omitted `table`; exported query JSON from tools that store the table elsewhere; forgetting that `--file` does not imply a default table.

Understand the failure class

Background: "Missing required field" and "field is required" errors: why libraries reject payloads that omit mandatory fields — this error's family across 20 libraries.

Related errors


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