Skip to content

Batch rendering rejects JSON files saved with a byte order mark #6604

Closed

Description

@AksharP5

Describe the bug

render --batch rejects otherwise valid batch data saved as UTF-8 with a byte order mark (BOM), or as BOM-marked UTF-16LE. This blocks batch files written by Windows editors and Windows PowerShell 5.1. The CLI already has a decoder for these encodings in jsonFlag.ts, but the batch reader bypasses it.

Minimal reproduction

From a repository checkout after the normal bun install and bun run build, create a one-second project and the two batch files:

node --input-type=module <<'JS'
import { mkdirSync, writeFileSync, copyFileSync } from 'node:fs';
mkdirSync('bom-batch');
writeFileSync('bom-batch/index.html', `<!doctype html>
<html lang="en" data-composition-variables='[{"id":"title","type":"string","label":"Title","default":"Default"}]'>
<head><meta charset="UTF-8"><title>Batch encoding reproduction</title>
<script src="gsap.min.js"></script>
<style>body{margin:0;background:#111;color:#fff;font-family:sans-serif}#root{width:100%;height:100%;display:grid;place-items:center}h1{font-size:36px}</style></head>
<body><div id="root" data-composition-id="main" data-width="320" data-height="180" data-duration="1">
<h1 class="clip" data-start="0" data-duration="1" data-track-index="0"><span data-var-text="title">Default</span></h1>
</div><script>window.__timelines["main"]=gsap.timeline({paused:true});</script></body></html>
`);
copyFileSync('packages/player/node_modules/gsap/dist/gsap.min.js', 'bom-batch/gsap.min.js');
for (const encoding of ['utf8', 'utf16le']) {
  writeFileSync(`bom-batch/rows-${encoding}.json`, Buffer.from('\uFEFF[{"title":"Café"}]', encoding));
}
JS

Steps to reproduce

cd bom-batch
node --import ../node_modules/tsx/dist/loader.mjs ../packages/cli/src/cli.ts render \
  --batch rows-utf8.json --output 'renders/{index}.mp4' \
  --fps 1 --workers 1 --json --quiet --strict-variables

Repeat with --batch rows-utf16le.json. The same problem occurs through the built packages/cli/bin/hyperframes.mjs entry point.

Expected behavior

Decode the file's encoding marker, parse the row and render one video containing Café, as with the same JSON in unmarked UTF-8.

Actual behavior

Both commands exit 1 before rendering with Invalid JSON in --batch. UTF-8 reports Unexpected token at U+FEFF; UTF-16LE reports Unexpected token at U+FFFD after the bytes are decoded as UTF-8. No batch output is produced.

Environment

  • Baseline: 7e92aec502c6a56488807c3cf9edb8371c854abd (CLI 0.8.209).
  • Linux arm64, Node 24.22.1, Bun 1.4.4, FFmpeg/FFprobe 7.0.2, system Chromium 156.0.8078.47.
  • Byte-exact UTF-8 BOM and UTF-16LE BOM fixtures were generated on Linux. Native Windows shell execution was not tested.

Additional context

The matching unmarked UTF-8 control renders successfully. Reusing the existing decoder makes both marked inputs render successfully too: each result reports total: 1, completed: 1, failed: 0, durationMs: 1000, with title: "Café". FFprobe confirms H.264, 320×180 and a 1-second duration; decoded frames were inspected.

Related work checked: #5725 covers project configuration, #6580 covers HTML decoding, and #6591 covers undefined injected readers for --variables-file. None changes this batch-file reader.

Activity

  1. added
    bugSomething isn't working
    triage/readyAccepted scope, current evidence, acceptance criteria, and validation path are recorded.
    on Oct 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingtriage/readyAccepted scope, current evidence, acceptance criteria, and validation path are recorded.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions