{"record":{"id":"20c7068c29d8a96d","repo":"JuliusBrussee/caveman","slug":"eval-evidence-file-contains-no-records","errorCode":null,"errorMessage":"eval evidence file contains no records","messagePattern":"eval evidence file contains no records","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/cli/src/index.ts","lineNumber":17163,"sourceCode":"  if (data.byteLength > 4 * 1024 * 1024) throw new Error(\"eval evidence file exceeds 4 MiB batch limit\");\n\n  const items: Record<string, unknown>[] = [];\n  for (const [index, rawLine] of data.toString(\"utf8\").split(/\\r?\\n/).entries()) {\n    const line = rawLine.trim();\n    if (!line) continue;\n    let parsed: unknown;\n    try {\n      parsed = JSON.parse(line);\n    } catch {\n      throw new Error(`eval evidence line ${index + 1} is not valid JSON`);\n    }\n    if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n      throw new Error(`eval evidence line ${index + 1} must be a JSON object`);\n    }\n    items.push(parsed as Record<string, unknown>);\n    if (items.length > 1000) throw new Error(\"eval evidence batch exceeds 1000 records\");\n  }\n  if (items.length === 0) throw new Error(\"eval evidence file contains no records\");\n\n  const cfg = await config();\n  const project = flagFrom(argv, \"--project\", cfg.projectId ?? \"\");\n  const response = await fetch(`${cfg.baseURL}/api/v1/eval-evidence/batches`, {\n    method: \"POST\",\n    headers: {\n      authorization: `Bearer ${cfg.token}`,\n      \"content-type\": \"application/json\",\n      \"x-cave-csrf\": \"cli\",\n    },\n    body: JSON.stringify({\n      ...(project ? { project_id: project } : {}),\n      dry_run: argv.includes(\"--dry-run\"),\n      items,\n    }),\n  });\n  const body = await response.json();\n  if (!response.ok) throw new Error(`eval evidence import failed (${response.status}): ${JSON.stringify(body)}`);","sourceCodeStart":17145,"sourceCodeEnd":17181,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/5184b3d11ac6a1acb7d44b9bfaa31698157cff97/packages/cli/src/index.ts#L17145-L17181","documentation":"Emptiness guard: after skipping blank lines, the evidence file yielded zero records, so there is nothing to POST. Distinct from the parse and shape errors — the file parsed fine, it simply contains no records. Usually a symptom that the producing eval run failed or the path points at a placeholder.","triggerScenarios":"A zero-byte file; a file containing only newlines/whitespace; a wrong path pointing at an accidentally created empty file; a generator whose filter removed every row.","commonSituations":"CI creating the artifact with touch before a failed produce step; glob patterns matching an empty placeholder; upstream eval run writing no rows.","solutions":["Check the pipeline that produced the file — an empty export usually means the eval run itself failed","Point the command at the real artifact path","Skip the import step when the file has no records instead of failing the job"],"exampleFix":"# before\ncaveman audit eval-import empty.jsonl\n# after\n[ -s evidence.jsonl ] && caveman audit eval-import evidence.jsonl || echo 'no records — skipping'","handlingStrategy":"validation","validationCode":"import { stat } from 'node:fs/promises';\nconst { size } = await stat(file);\nif (size === 0) throw new Error('evidence file is empty — the producing step likely failed');","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use `[ -s file ]` guards in CI so empty artifacts skip import","Fail the producing eval step loudly so empty artifacts never reach import","Log record counts at each pipeline stage"],"tags":["cli","empty-file","eval","import"],"backgroundTag":"empty-input-file","analyzedSha":"5184b3d11ac6a1acb7d44b9bfaa31698157cff97","analyzedAt":"2026-08-18T03:14:35.516Z","contentChangedAt":"2026-08-18T03:14:35.516Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}