actualbudget/actual · error · Error

Query result missing data

Error message

Query result missing data

What it means

After executing the query via api.aqlQuery, registerQueryCommand expects the result to be an object containing a `data` property (the standard AQL result shape). If the API returns something else — a non-object or an object without `data` — the CLI throws this error instead of printing garbage. This usually indicates an API/server protocol mismatch rather than a bad query.

Source

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

    )
    .addHelpText('after', RUN_EXAMPLES)
    .action(async cmdOpts => {
      const opts = program.opts();
      await withConnection(
        opts,
        async () => {
          const parsed = cmdOpts.file ? readJsonInput(cmdOpts) : undefined;
          if (parsed !== undefined && !isRecord(parsed)) {
            throw new Error('Query file must contain a JSON object');
          }
          const queryObj = parsed
            ? buildQueryFromFile(parsed, cmdOpts.table)
            : buildQueryFromFlags(cmdOpts);

          const result = await api.aqlQuery(queryObj);

          if (!isRecord(result) || !('data' in result)) {
            throw new Error('Query result missing data');
          }

          if (cmdOpts.count) {
            printOutput({ count: result.data }, opts.format);
          } else {
            printOutput(result.data, opts.format);
          }
        },
        { mutates: false },
      );
    });

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

View on GitHub (pinned to d4334cb6e6)

Solutions

  1. Check that @actual-app/api (CLI dependency) and the sync-server are on compatible/updated versions; upgrade both with yarn
  2. Run the query again after confirming the server is healthy (other commands like `actual accounts` succeed)
  3. If you run a proxy or custom middleware in front of the server, ensure it does not alter the response body
  4. Report a bug if a stock server and matching CLI version still reproduce it

Example fix

// before (mismatched versions)
npx -p @actual-app/cli@old actual query transactions

// after
yarn global upgrade @actual-app/cli  # or reinstall matching the server version
actual query transactions
Defensive patterns

Strategy: try-catch

Validate before calling

// pin compatible versions before invoking the CLI
const cli = JSON.parse(readFileSync('node_modules/@actual-app/api/package.json','utf8'));
console.assert(cli.version === installedServerVersion, 'CLI/API and server versions must match');

Type guard

function hasAqlData(r: unknown): r is { data: unknown } {
  return typeof r === 'object' && r !== null && 'data' in r;
}

Try / catch

try {
  const { stdout } = await run(['actual', 'query', 'transactions']);
  const parsed = JSON.parse(stdout);
} catch (e) {
  if (String(e.message).includes('Query result missing data')) {
    console.error('Check CLI/server version compatibility; inspect raw server response');
  } else throw e;
}

Prevention

When it happens

Trigger: Calling `actual query` against a server or @actual-app/api version whose aqlQuery return shape differs (e.g. returns { rows } or a bare array); a mocked/proxied server returning an error payload without `data`; piping output of an older CLI to a newer server or vice versa.

Common situations: Version skew between CLI and sync-server after an upgrade; custom server middleware stripping fields; running against an incompatibly-patched Actual server.

Related errors


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