{"record":{"id":"5013d7222ef36c0d","repo":"lobehub/lobehub","slug":"expected-a-json-array-of-result-items-or-items","errorCode":null,"errorMessage":"Expected a JSON array of result items (or { items: [...] })","messagePattern":"Expected a JSON array of result items \\(or (.+?)\\)","errorType":"validation","errorClass":"InvalidArgumentError","httpStatus":null,"severity":"error","filePath":"apps/cli/src/commands/eval.ts","lineNumber":999,"sourceCode":"    .option('--json', 'Output JSON envelope')\n    .action(async (options: JsonOption & { file: string; runId: string }) =>\n      executeCommand(\n        options,\n        async () => {\n          const raw =\n            options.file === '-'\n              ? await new Promise<string>((resolve, reject) => {\n                  let data = '';\n                  process.stdin.on('data', (chunk) => (data += chunk));\n                  process.stdin.on('end', () => resolve(data));\n                  process.stdin.on('error', reject);\n                })\n              : await readFile(options.file, 'utf8');\n\n          const parsed = JSON.parse(raw);\n          const items = Array.isArray(parsed) ? parsed : parsed.items;\n          if (!Array.isArray(items) || items.length === 0) {\n            throw new InvalidArgumentError(\n              'Expected a JSON array of result items (or { items: [...] })',\n            );\n          }\n\n          const client = await getTrpcClient();\n          return client.agentEvalExternal.reportResultsBatch.mutate({\n            items,\n            runId: options.runId,\n          } as any);\n        },\n        `Reported batch results for run ${pc.bold(options.runId)}`,\n      ),\n    );\n\n  // ============================================\n  // Eval Thread Operations (external eval API)\n  // ============================================\n  evalCmd","sourceCodeStart":981,"sourceCodeEnd":1017,"githubUrl":"https://github.com/lobehub/lobehub/blob/10f24d7ade75139093a9373b364f6bc91f3cd7db/apps/cli/src/commands/eval.ts#L981-L1017","documentation":"Thrown during eval batch result reporting when the parsed JSON from the input file or stdin is neither a top-level JSON array nor an object with an 'items' array — or when the resulting array is empty. The batch report command expects a non-empty list of result items; a single object, a non-array value, or an empty array are all rejected before the server mutation.","triggerScenarios":"Running lh eval report-batch --file <path> --run-id <id> where the file (or stdin) contains: a single JSON object (not wrapped in an array or {items:[...]}), an empty array '[]', an object without an 'items' key, or an object where items is not an array. Also fires when piping an empty or malformed payload via --file -.","commonSituations":"1) File contains a single result object instead of an array of results. 2) Empty file or empty array. 3) File has a different wrapper key (e.g. {results:[...]} instead of {items:[...]}). 4) Stdin pipe produced no data or invalid JSON. 5) JSON.parse itself succeeded but the structure is wrong.","solutions":["Ensure the file contains a JSON array: [{...}, {...}] or an object with an items array: {\"items\":[{...}]}.","Verify the array is non-empty — at least one result item is required.","If wrapping in an object, use the exact key 'items': {\"items\":[...]}.","Validate the structure: jq 'if type==\"array\" then length else .items|length end' file.json should be > 0.","If using stdin (--file -), ensure the pipe actually produces output: cat results.json | lh eval report-batch --file - --run-id run-1."],"exampleFix":"// before (single object, not an array):\n// results.json:\n{ \"caseId\": \"c1\", \"status\": \"pass\" }\n// after (array of items):\n// results.json:\n[{ \"caseId\": \"c1\", \"status\": \"pass\" }]\n// or (items wrapper):\n{ \"items\": [{ \"caseId\": \"c1\", \"status\": \"pass\" }] }","handlingStrategy":"validation","validationCode":"import { readFile } from 'node:fs/promises';\n\nfunction validateBatchItems(raw: string): unknown[] {\n  const parsed = JSON.parse(raw);\n  const items = Array.isArray(parsed) ? parsed : parsed.items;\n  if (!Array.isArray(items) || items.length === 0) {\n    throw new Error('Expected a JSON array of result items (or { items: [...] })');\n  }\n  return items;\n}\n// Usage: const items = validateBatchItems(await readFile('results.json', 'utf8'));","typeGuard":"function isBatchPayload(value: unknown): value is unknown[] | { items: unknown[] } {\n  if (Array.isArray(value)) return true;\n  return typeof value === 'object' && value !== null && Array.isArray((value as any).items);\n}","tryCatchPattern":null,"preventionTips":["Ensure batch result files contain a non-empty JSON array or { items: [...] }.","Validate with jq: jq 'if type==\"array\" then length else .items|length end' file.json should be > 0.","Use the exact key 'items' when wrapping in an object.","Verify stdin pipes produce output before using --file -."],"tags":["cli","validation","json","eval","batch"],"backgroundTag":null,"analyzedSha":"10f24d7ade75139093a9373b364f6bc91f3cd7db","analyzedAt":"2026-08-12T11:43:19.543Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}