remotion-dev/remotion · error · Error

Expected a Remotion Caption[] JSON array.

Error message

Expected a Remotion Caption[] JSON array.

What it means

parseCaptionFile in Remotion Studio parses a caption .json file and validates it against the Caption[] shape from @remotion/captions. This error is thrown when the parsed JSON is valid JSON but its top-level value is not an array. The parser only accepts an array of caption objects at the root.

Source

Thrown at packages/studio/src/components/parse-caption-file.ts:32

}: {
	fileName: string;
	contents: string;
}): Caption[] => {
	if (!fileName.toLowerCase().endsWith('.json')) {
		throw new Error('Unsupported caption file. Choose a .json file.');
	}

	let parsed: unknown;
	try {
		parsed = JSON.parse(contents);
	} catch (error) {
		throw new Error(
			`Invalid JSON: ${error instanceof Error ? error.message : String(error)}`,
		);
	}

	if (!Array.isArray(parsed)) {
		throw new Error('Expected a Remotion Caption[] JSON array.');
	}

	let previousStart: number | null = null;
	for (const [index, caption] of parsed.entries()) {
		const path = `captions[${index}]`;
		if (!isObject(caption)) {
			throw new Error(`${path} must be an object.`);
		}

		if (typeof caption.text !== 'string') {
			throw new Error(`${path}.text must be a string.`);
		}

		if (!isFiniteNumber(caption.startMs) || caption.startMs < 0) {
			throw new Error(`${path}.startMs must be a finite, non-negative number.`);
		}

		if (!isFiniteNumber(caption.endMs) || caption.endMs < 0) {

View on GitHub (pinned to b2f4e34732)

Solutions

  1. Wrap the captions in a bare top-level JSON array: [ {...}, {...} ]
  2. If the file is {"captions": [...]}, pass the inner array instead: JSON.parse(contents).captions
  3. Re-export the captions from the source tool choosing the Remotion JSON format

Example fix

// before
{"captions": [{"text": "hi", "startMs": 0, "endMs": 1000}]}
// after
[{"text": "hi", "startMs": 0, "endMs": 1000}]
Defensive patterns

Strategy: validation

Validate before calling

const parsed: unknown = JSON.parse(contents);
if (!Array.isArray(parsed)) {
  throw new Error('Caption file must be a JSON array at the top level.');
}

Type guard

const isCaptionArray = (v: unknown): v is unknown[] =>
  Array.isArray(v);

Try / catch

try {
  const captions = parseCaptionFile({fileName, contents});
} catch (e) {
  console.error('Invalid caption file:', (e as Error).message);
  // show a user-facing parse error / abort import
}

Prevention

When it happens

Trigger: Calling parseCaptionFile({fileName: 'captions.json', contents: '...'}) where JSON.parse(contents) yields an object (e.g. {captions: [...]}) or any non-array value (string, number, null).

Common situations: Exporting captions wrapped in an object envelope instead of a bare array; hand-editing a caption file and accidentally adding a wrapper; a tool exporting a custom format whose root is an object.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of remotion-dev/remotion@b2f4e34732 (2026-09-09). Data as JSON: /api/errors/881ff7ce736eea38. Report an issue: GitHub.