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

  1. Make every element of the rows array a JSON object, e.g. `[{"out":"a.mp4"},{"out":"b.mp4"}]`.
  2. If exporting from a spreadsheet, ensure headers map to keys (row = {column:value}).
  3. 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

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


AI-assisted analysis of heygen-com/hyperframes@c2996c8626 (2026-08-12). Data as JSON: /api/errors/bc9e34eee66976ec. Report an issue: GitHub.