Egonex-AI/Understand-Anything · error · Error
Batch artifact does not match the required shape
Error message
Batch artifact does not match the required shape
What it means
Thrown by validateBatchArtifact when batches.json (the output of the batching worker) does not satisfy the contract the benchmark needs to size agent input. It enforces schemaVersion===1, a non-empty algorithm string, a batches array whose length equals totalBatches, and a per-batch shape of {batchIndex, files[], batchImportData, neighborMap}. This is a hard gate because the agent-input byte estimate (JSON.stringify of files+batchImportData+neighborMap) is computed unconditionally right after this check.
Source
Thrown at scripts/lib/large-repo-benchmark.mjs:771
function validateBatchArtifact(batches) {
if (
!isRecord(batches) ||
batches.schemaVersion !== 1 ||
typeof batches.algorithm !== 'string' ||
batches.algorithm.length === 0 ||
!Array.isArray(batches.batches) ||
!isNonNegativeInteger(batches.totalBatches) ||
batches.totalBatches !== batches.batches.length ||
batches.batches.some(
(batch) =>
!isRecord(batch) ||
!isNonNegativeInteger(batch.batchIndex) ||
!Array.isArray(batch.files) ||
!isRecord(batch.batchImportData) ||
!isRecord(batch.neighborMap),
)
) {
throw new Error('Batch artifact does not match the required shape');
}
}
function markArtifactFailure(stage, stageName, error, redactionRoots) {
const rawMessage = error instanceof Error ? error.message : String(error);
const safeMessage = sanitizeBounded(
`${stageName} stage produced an invalid artifact: ${rawMessage}`,
redactionRoots,
);
stage.status = 'failed';
stage.stderr = safeMessage.text;
stage.stderrTruncated ||= safeMessage.truncated;
}
function fileSizeOrZero(path) {
try {
return statSync(path).size;
} catch {View on GitHub (pinned to 32944829e7)
Solutions
- Open artifactRoot/batches.json and confirm schemaVersion===1, a non-empty algorithm string, and totalBatches === batches.length.
- Re-run the batching stage on its prior inputs (scan-result-with-imports.json) and inspect stderr; a crash there usually leaves totalBatches unset.
- If you swapped in a different batching algorithm, ensure it still emits schemaVersion:1 and the four required per-batch fields.
- Delete batches.json and the artifactRoot intermediate so the benchmark regenerates it from the validated scan+import artifacts.
- Verify the import stage (error 20) passed — batching depends on batchImportData/neighborMap produced upstream, and a skipped import stage yields empty maps that some custom batchers may omit.
Example fix
// before: batcher emits arrays without the envelope
{ "batches": [ { "files": ["a.ts"] } ] }
// after: full validated shape
{
"schemaVersion": 1,
"algorithm": "greedy-import-locality",
"totalBatches": 1,
"batches": [
{ "batchIndex": 0, "files": ["a.ts"], "batchImportData": {}, "neighborMap": {} }
]
} Defensive patterns
Strategy: validation
Validate before calling
function isValidBatchArtifact(v) {
if (typeof v !== 'object' || v === null) return false;
if (v.schemaVersion !== 1) return false;
if (typeof v.algorithm !== 'string' || v.algorithm.length === 0) return false;
if (!Array.isArray(v.batches)) return false;
if (!Number.isInteger(v.totalBatches) || v.totalBatches !== v.batches.length) return false;
for (const b of v.batches) {
if (typeof b !== 'object' || b === null) return false;
if (!Number.isInteger(b.batchIndex) || b.batchIndex < 0) return false;
if (!Array.isArray(b.files)) return false;
if (typeof b.batchImportData !== 'object' || b.batchImportData === null) return false;
if (typeof b.neighborMap !== 'object' || b.neighborMap === null) return false;
}
return true;
} Type guard
function isBatchArtifact(v) {
if (typeof v !== 'object' || v === null) return false;
const o = v;
return o.schemaVersion === 1
&& typeof o.algorithm === 'string' && o.algorithm.length > 0
&& Array.isArray(o.batches)
&& Number.isInteger(o.totalBatches) && o.totalBatches === o.batches.length
&& o.batches.every((b) =>
b !== null && typeof b === 'object'
&& Number.isInteger(b.batchIndex) && b.batchIndex >= 0
&& Array.isArray(b.files)
&& typeof b.batchImportData === 'object' && b.batchImportData !== null
&& typeof b.neighborMap === 'object' && b.neighborMap !== null);
} Try / catch
try {
validateBatchArtifact(batches);
} catch (e) {
console.error('batches.json shape invalid:', e.message, batchesPath);
throw e;
} Prevention
- Custom batchers must emit schemaVersion:1, a non-empty algorithm, totalBatches === batches.length, and all four per-batch fields.
- Never edit batches.json by hand without updating totalBatches to match.
- Re-run the batcher rather than patching its output.
When it happens
Trigger: The benchmark reads artifactRoot/batches.json after batchStage.status === 'ok' and calls validateBatchArtifact(batches). Throws when schemaVersion !== 1, algorithm is missing/empty/non-string, batches is not an array, totalBatches !== batches.length, or any batch is missing batchIndex (non-negative int), files (array), batchImportData (record), or neighborMap (record).
Common situations: A custom or out-of-date batching implementation that omits schemaVersion or the algorithm tag. A partial write where totalBatches was updated but batches truncated (interrupted write / OOM kill mid-stream). A neighborMap that came back null from a worker that skipped import enrichment. Editing batches.json by hand and forgetting the totalBatches counter.
Related errors
- Import artifact does not match the required shape
- Scan artifact does not match the required shape
- Invalid knowledge graph: ${result.fatal ?? "unknown error"}
- Invalid domain graph: ${result.fatal ?? "unknown error"}
- Benchmark stage failed: ${stage.name}
AI-assisted analysis of Egonex-AI/Understand-Anything@32944829e7 (2026-08-12).
Data as JSON: /api/errors/c85ce0e2f8d9f13d.
Report an issue: GitHub.