{"record":{"id":"a15bead77c84ed66","repo":"actualbudget/actual","slug":"query-result-missing-data","errorCode":null,"errorMessage":"Query result missing data","messagePattern":"Query result missing data","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/cli/src/commands/query.ts","lineNumber":318,"sourceCode":"    )\n    .addHelpText('after', RUN_EXAMPLES)\n    .action(async cmdOpts => {\n      const opts = program.opts();\n      await withConnection(\n        opts,\n        async () => {\n          const parsed = cmdOpts.file ? readJsonInput(cmdOpts) : undefined;\n          if (parsed !== undefined && !isRecord(parsed)) {\n            throw new Error('Query file must contain a JSON object');\n          }\n          const queryObj = parsed\n            ? buildQueryFromFile(parsed, cmdOpts.table)\n            : buildQueryFromFlags(cmdOpts);\n\n          const result = await api.aqlQuery(queryObj);\n\n          if (!isRecord(result) || !('data' in result)) {\n            throw new Error('Query result missing data');\n          }\n\n          if (cmdOpts.count) {\n            printOutput({ count: result.data }, opts.format);\n          } else {\n            printOutput(result.data, opts.format);\n          }\n        },\n        { mutates: false },\n      );\n    });\n\n  query\n    .command('tables')\n    .description('List available tables for querying')\n    .action(() => {\n      const opts = program.opts();\n      const tables = Object.keys(TABLE_SCHEMA).map(name => ({ name }));","sourceCodeStart":300,"sourceCodeEnd":336,"githubUrl":"https://github.com/actualbudget/actual/blob/d4334cb6e6123f4d3bcea1ad6166608884c7e658/packages/cli/src/commands/query.ts#L300-L336","documentation":"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.","triggerScenarios":"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.","commonSituations":"Version skew between CLI and sync-server after an upgrade; custom server middleware stripping fields; running against an incompatibly-patched Actual server.","solutions":["Check that @actual-app/api (CLI dependency) and the sync-server are on compatible/updated versions; upgrade both with yarn","Run the query again after confirming the server is healthy (other commands like `actual accounts` succeed)","If you run a proxy or custom middleware in front of the server, ensure it does not alter the response body","Report a bug if a stock server and matching CLI version still reproduce it"],"exampleFix":"// before (mismatched versions)\nnpx -p @actual-app/cli@old actual query transactions\n\n// after\nyarn global upgrade @actual-app/cli  # or reinstall matching the server version\nactual query transactions","handlingStrategy":"try-catch","validationCode":"// pin compatible versions before invoking the CLI\nconst cli = JSON.parse(readFileSync('node_modules/@actual-app/api/package.json','utf8'));\nconsole.assert(cli.version === installedServerVersion, 'CLI/API and server versions must match');","typeGuard":"function hasAqlData(r: unknown): r is { data: unknown } {\n  return typeof r === 'object' && r !== null && 'data' in r;\n}","tryCatchPattern":"try {\n  const { stdout } = await run(['actual', 'query', 'transactions']);\n  const parsed = JSON.parse(stdout);\n} catch (e) {\n  if (String(e.message).includes('Query result missing data')) {\n    console.error('Check CLI/server version compatibility; inspect raw server response');\n  } else throw e;\n}","preventionTips":["Upgrade @actual-app/cli (and its bundled API) and the sync-server together","Avoid custom proxies/middleware that rewrite API response bodies","Smoke-test with a cheap command (`actual accounts`) after any version change"],"tags":["cli","aql","api-response","version-mismatch"],"backgroundTag":"unexpected-api-response-shape","analyzedSha":"d4334cb6e6123f4d3bcea1ad6166608884c7e658","analyzedAt":"2026-08-29T01:02:11.213Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}