heygen-com/hyperframes · error · BatchRenderInputError

Missing value for placeholder {${key}} in row ${index}.

Error message

Missing value for placeholder {${key}} in row ${index}.

What it means

BatchRenderInputError with title 'Invalid output template', thrown by placeholderValue when the output template references a {key} that is not present in the current row (Object.hasOwn(row, key) is false). The special placeholder {index} (the row's position) is always available and never triggers this error. The message names both the missing key and the row index.

Source

Thrown at packages/cli/src/commands/batchRender.ts:127

  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];
  if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
    return String(value);
  }

  throw new BatchRenderInputError(
    "Invalid output template",
    `Placeholder {${key}} in row ${index} must resolve to a string, number, or boolean.`,
  );
}

export function resolveOutputTemplate(
  template: string,

View on GitHub (pinned to c2996c8626)

Solutions

  1. Make the placeholder name match a key present in every row, or add the key to the rows that lack it.
  2. Use the always-available {index} placeholder if you only need a per-row counter.
  3. Validate up front that every placeholder token in the template resolves against every row.

Example fix

# before: template references {name}, some rows omit it
hyperframes render --batch '[{"out":"a"}]' --output 'out-{name}.mp4'

# after: use a key every row has, or {index}
hyperframes render --batch '[{"out":"a"}]' --output 'out-{index}.mp4'
Defensive patterns

Strategy: validation

Validate before calling

const PLACEHOLDER_RE = /\{([A-Za-z0-9_.-]+)\}/g;
function assertTemplateResolves(template: string, rows: Record<string, unknown>[]) {
  const keys = new Set<string>();
  for (const m of template.matchAll(PLACEHOLDER_RE)) keys.add(m[1]);
  rows.forEach((row, i) => {
    for (const k of keys) {
      if (k !== 'index' && !Object.hasOwn(row, k)) {
        throw new Error(`Row ${i} missing placeholder key {${k}}`);
      }
    }
  });
}

Try / catch

try {
  resolveOutputTemplate(template, row, index);
} catch (err) {
  if (err instanceof BatchRenderInputError && err.title === 'Invalid output template') {
    // use {index} or add the missing key to every row
  }
}

Prevention

When it happens

Trigger: An output template like `out-{name}.mp4` where some rows omit the `name` key; a typo in the placeholder name versus the row's keys; mixed schemas across rows where only some carry the field.

Common situations: Template authored against one row shape but the batch contains rows with fewer keys; a key renamed in the data but not in the template; case mismatch ({Name} vs {name}).

Related errors


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