lobehub/lobehub · error · InvalidArgumentError
Expected a JSON array of result items (or { items: [...] })
Error message
Expected a JSON array of result items (or { items: [...] }) What it means
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.
Source
Thrown at apps/cli/src/commands/eval.ts:999
.option('--json', 'Output JSON envelope')
.action(async (options: JsonOption & { file: string; runId: string }) =>
executeCommand(
options,
async () => {
const raw =
options.file === '-'
? await new Promise<string>((resolve, reject) => {
let data = '';
process.stdin.on('data', (chunk) => (data += chunk));
process.stdin.on('end', () => resolve(data));
process.stdin.on('error', reject);
})
: await readFile(options.file, 'utf8');
const parsed = JSON.parse(raw);
const items = Array.isArray(parsed) ? parsed : parsed.items;
if (!Array.isArray(items) || items.length === 0) {
throw new InvalidArgumentError(
'Expected a JSON array of result items (or { items: [...] })',
);
}
const client = await getTrpcClient();
return client.agentEvalExternal.reportResultsBatch.mutate({
items,
runId: options.runId,
} as any);
},
`Reported batch results for run ${pc.bold(options.runId)}`,
),
);
// ============================================
// Eval Thread Operations (external eval API)
// ============================================
evalCmdView on GitHub (pinned to 10f24d7ade)
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.
Example fix
// before (single object, not an array):
// results.json:
{ "caseId": "c1", "status": "pass" }
// after (array of items):
// results.json:
[{ "caseId": "c1", "status": "pass" }]
// or (items wrapper):
{ "items": [{ "caseId": "c1", "status": "pass" }] } Defensive patterns
Strategy: validation
Validate before calling
import { readFile } from 'node:fs/promises';
function validateBatchItems(raw: string): unknown[] {
const parsed = JSON.parse(raw);
const items = Array.isArray(parsed) ? parsed : parsed.items;
if (!Array.isArray(items) || items.length === 0) {
throw new Error('Expected a JSON array of result items (or { items: [...] })');
}
return items;
}
// Usage: const items = validateBatchItems(await readFile('results.json', 'utf8')); Type guard
function isBatchPayload(value: unknown): value is unknown[] | { items: unknown[] } {
if (Array.isArray(value)) return true;
return typeof value === 'object' && value !== null && Array.isArray((value as any).items);
} Prevention
- 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 -.
When it happens
Trigger: 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 -.
Common situations: 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.
Related errors
- Invalid JSON value for --result-json
- --result-json must be a JSON object
- Invalid JSON value for ${option}
- ${option} must be a JSON object
- payload must be a JSON object
AI-assisted analysis of lobehub/lobehub@10f24d7ade (2026-08-12).
Data as JSON: /api/errors/5013d7222ef36c0d.
Report an issue: GitHub.