actualbudget/actual · error · Error

--count and --select are mutually exclusive

Error message

--count and --select are mutually exclusive

What it means

The `actual query` command supports `--count` (returns only the number of matching rows) and `--select` (choose which fields to return). Counting discards row projection entirely, so passing both is rejected by buildQueryFromFlags before the query runs.

Source

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

  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(','));
  } else if (last !== undefined) {
    queryObj = queryObj.select(LAST_DEFAULT_SELECT);
  }

  const filterStr = cmdOpts.filter ?? cmdOpts.where;
  if (filterStr) {
    queryObj = queryObj.filter(JSON.parse(filterStr));
  }

  const orderByStr =

View on GitHub (pinned to d4334cb6e6)

Solutions

  1. Drop --select when using --count; the result is a single { count: N } object
  2. If you need per-group counts, use --group-by with --count or select the field and count rows client-side
  3. If you need the rows, drop --count and keep --select

Example fix

// before
actual query transactions --count --select date,amount

// after
actual query transactions --count
Defensive patterns

Strategy: validation

Validate before calling

const flags = ['--count', ...(select ? ['--select', select] :) []];
if (useCount && select) throw new Error('--select is meaningless with --count; remove one');

Type guard

function hasCountSelectConflict(opts: { count?: boolean; select?: string }): boolean {
  return opts.count === true && opts.select !== undefined;
}

Try / catch

try {
  await run(['actual', 'query', table, ...flags]);
} catch (e) {
  if (String(e.message).includes('--count and --select')) {
    console.error('Use --count alone, or --select for row data');
  } else throw e;
}

Prevention

When it happens

Trigger: Running `actual query transactions --count --select date,amount` — both flags present. Also occurs when a shell alias or wrapper always adds --select while the user adds --count.

Common situations: Users wanting totals per-field assume --count works with --select; scripts migrating commands that previously selected fields to a counting variant.

Related errors


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