heygen-com/hyperframes · error · BatchRenderInputError
Row ${index} must be a JSON object of variable values.
Error message
Row ${index} must be a JSON object of variable values. What it means
BatchRenderInputError with title 'Invalid batch row', thrown inside parseBatchRows' rows.map when a row is not a plain object (Record<string, unknown>). The message names the offending row index. Rows that are null, a primitive, or an array all trip this check; a row that is an object but lacks a key the output template needs trips error 98 instead.
Source
Thrown at packages/cli/src/commands/batchRender.ts:115
}
export function parseBatchRows(raw: string, source: string): Record<string, unknown>[] {
const parsed = parseJson(raw, source);
const rows = Array.isArray(parsed) ? parsed : isRecord(parsed) ? parsed.rows : undefined;
if (!Array.isArray(rows)) {
throw new BatchRenderInputError(
"Invalid batch payload",
'--batch must be a JSON array of objects, or an object with a "rows" array.',
);
}
if (rows.length === 0) {
throw new BatchRenderInputError("Empty batch", `${source} contains zero rows.`);
}
return rows.map((row, index) => {
if (!isRecord(row)) {
throw new BatchRenderInputError(
"Invalid batch row",
`Row ${index} must be a JSON object of variable values.`,
);
}
return row;
});
}
function placeholderValue(row: Record<string, unknown>, key: string, index: number): string {
if (key === "index") return String(index);
if (!Object.hasOwn(row, key)) {
throw new BatchRenderInputError(
"Invalid output template",
`Missing value for placeholder {${key}} in row ${index}.`,
);
}
const value = row[key];View on GitHub (pinned to c2996c8626)
Solutions
- Make every element of the rows array a JSON object, e.g. `[{"out":"a.mp4"},{"out":"b.mp4"}]`.
- If exporting from a spreadsheet, ensure headers map to keys (row = {column:value}).
- Validate each row with a JSON-schema or type guard before writing the batch file.
Example fix
# before: array of scalars
hyperframes render --batch '["a.mp4","b.mp4"]'
# after: array of objects
hyperframes render --batch '[{"out":"a.mp4"},{"out":"b.mp4"}]' Defensive patterns
Strategy: type-guard
Validate before calling
function assertRowsAreObjects(rows: unknown[]) {
rows.forEach((r, i) => {
if (r === null || typeof r !== 'object' || Array.isArray(r)) {
throw new Error(`Row ${i} is not a JSON object`);
}
});
} Type guard
function isRecord(value: unknown): value is Record<string, unknown> {
return value !== null && typeof value === 'object' && !Array.isArray(value);
} Try / catch
try {
parseBatchRows(raw, source);
} catch (err) {
if (err instanceof BatchRenderInputError && err.title === 'Invalid batch row') {
// rewrite each non-object element as { value: element }
}
} Prevention
- Ensure the data export emits an object per row (column header -> value).
- Validate each row with the isRecord type guard before writing the batch.
- Watch for null or array rows that slip in from cleaning steps.
When it happens
Trigger: An array like `["a", "b"]` (string rows), `[null]`, or `[[1,2]]` (nested arrays). Each element must itself be a JSON object.
Common situations: A data export that produced an array of scalars instead of objects; mixing row shapes in one batch; a templating bug that emitted the value instead of {key:value}.
Related errors
- Placeholder {${key}} in row ${index} must resolve to a strin
- ${source}: ${errorMessage(error)}
- --batch must be a JSON array of objects, or an object with a
- ${source} contains zero rows.
- Missing value for placeholder {${key}} in row ${index}.
AI-assisted analysis of heygen-com/hyperframes@c2996c8626 (2026-08-12).
Data as JSON: /api/errors/bc9e34eee66976ec.
Report an issue: GitHub.