remotion-dev/remotion · error · Error

The label parameter of delayRender() must be a string or und

Error message

The label parameter of delayRender() must be a string or undefined, got: ${JSON.stringify(label)}

What it means

delayRender() takes an optional label used in timeout/diagnostic messages. The label must be a string (or omitted/undefined, which becomes null internally). Passing any other type (number, object, array) is rejected because the label is interpolated into log/timeout strings and non-string values would produce useless diagnostics.

Source

Thrown at packages/core/src/delay-render.ts:67

 * Internal function that accepts environment as parameter.
 * This allows useDelayRender to control its own environment source.
 * @private
 */
type DelayRenderInternalOptions = {
	scope: DelayRenderScope;
	environment: RemotionEnvironment;
	label: string | null;
	options: DelayRenderOptions;
};

export const delayRenderInternal = ({
	scope,
	environment,
	label,
	options,
}: DelayRenderInternalOptions): number => {
	if (typeof label !== 'string' && label !== null) {
		throw new Error(
			'The label parameter of delayRender() must be a string or undefined, got: ' +
				JSON.stringify(label),
		);
	}

	const handle = Math.random();
	scope.remotion_delayRenderHandles.push(handle);
	const called = Error().stack?.replace(/^Error/g, '') ?? '';

	if (environment.isRendering) {
		const timeoutToUse =
			(options?.timeoutInMilliseconds ??
				scope.remotion_puppeteerTimeout ??
				defaultTimeout) - 2000;
		const retriesLeft = (options?.retries ?? 0) - (scope.remotion_attempt - 1);
		scope.remotion_delayRenderTimeouts[handle] = {
			label: label ?? null,
			startTime: Date.now(),

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Pass a string label or omit it: delayRender('loading data') or delayRender().
  2. Move options into the second argument: delayRender('label', {timeoutInMilliseconds: 10000}).
  3. Coerce safely: delayRender(String(label)) only if you genuinely mean it.

Example fix

// before
delayRender({timeoutInMilliseconds: 10000})

// after
delayRender('loading data', {timeoutInMilliseconds: 10000})
Defensive patterns

Strategy: validation

Validate before calling

const safeLabel =
  label === undefined || typeof label === 'string' ? label : String(label);
const handle = delayRender(safeLabel, options);

Type guard

const isValidDelayRenderLabel = (
  label: unknown,
): label is string | undefined =>
  label === undefined || typeof label === 'string';

Prevention

When it happens

Trigger: Calling delayRender(123), delayRender({name: 'load'}), delayRender(someObject), or delayRender(`${n}`) where the template accidentally yields a non-string. Also triggered by passing a config object where a label string was expected.

Common situations: Misreading the signature and passing an options object as the first arg; passing a numeric id instead of a descriptive label; variable that is sometimes undefined-typed but actually holds a non-string.

Related errors


AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12). Data as JSON: /api/errors/c05eb7efad428f54. Report an issue: GitHub.