remotion-dev/remotion · error · Error

Renderer S3 status must be an object

Error message

Renderer S3 status must be an object

What it means

parseS3RendererStatus() in @remotion/serverless-client strictly validates the JSON parsed from renders/{renderId}/transport/chunks/{chunk}/attempt-{attempt}/status.json before the orchestrator trusts it. First invariant: the parsed value must be a non-null object. JSON literals like null, numbers, strings, or booleans (a body of 'null', '0', 'true', '""') fail here.

Source

Thrown at packages/serverless-client/src/renderer-transport.ts:99

		attempt: number;
	},
	artifactIndex: number,
) => `${rendererTransportAttemptPrefix(options)}/artifacts/${artifactIndex}`;

const isNumber = (value: unknown): value is number =>
	typeof value === 'number' && Number.isFinite(value);

export const parseS3RendererStatus = ({
	value,
	expectedChunk,
	expectedAttempt,
}: {
	value: unknown;
	expectedChunk: number;
	expectedAttempt: number;
}): S3RendererStatus => {
	if (typeof value !== 'object' || value === null) {
		throw new Error('Renderer S3 status must be an object');
	}

	const status = value as Record<string, unknown>;
	if (status.schema !== 1) {
		throw new Error(
			`Unsupported renderer S3 status schema: ${String(status.schema)}`,
		);
	}

	if (status.chunk !== expectedChunk || status.attempt !== expectedAttempt) {
		throw new Error(
			`Renderer S3 status identifies chunk ${String(status.chunk)}, attempt ${String(status.attempt)}; expected chunk ${expectedChunk}, attempt ${expectedAttempt}`,
		);
	}

	if (
		typeof status.lambdaInvoked !== 'boolean' ||
		!isNumber(status.renderedFrames) ||

View on GitHub (pinned to 10db9de073)

Solutions

  1. Download and inspect the offending object: aws s3 cp s3://<bucket>/<render-prefix>/transport/chunks/<chunk>/attempt-<n>/status.json - and confirm the body is an object literal.
  2. Delete the render's transport prefix and retry with a fresh renderId.
  3. Check whether any other process writes to the renders/ prefix in that bucket.
  4. If using an S3-compatible provider, verify it returns correct object bodies under concurrent access; test against real S3 to isolate the fault.
Defensive patterns

Strategy: retry

Validate before calling

# Inspect the object the parser rejected before retrying
aws s3 cp "s3://$BUCKET/renders/$RENDER_ID/transport/chunks/$CHUNK/attempt-$ATTEMPT/status.json" - \
  | jq 'type'   # must print "object"

Try / catch

try {
  await renderMediaOnCloudRun({...input, renderId: makeRenderId()});
} catch (err) {
  if (err.message.includes('Renderer S3 status must be an object')) {
    // corrupt/foreign status.json - sweep the prefix and retry with a fresh renderId
    await deleteRenderFolder(bucketName, renderId);
    await renderMediaOnCloudRun({...input, renderId: makeRenderId()});
  } else {
    throw err;
  }
}

Prevention

When it happens

Trigger: status.json contains a JSON literal instead of an object - a placeholder or empty value written by an interrupted/broken uploader, or a value written by a non-Remotion process sharing the renders/ prefix.

Common situations: S3-compatible endpoints (MinIO and similar) returning unexpected bodies under load; stray jobs writing to the render prefix; corrupted multipart uploads of small objects.

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@10db9de073 (2026-08-22). Data as JSON: /api/errors/d8c34a440823e16b. Report an issue: GitHub.