remotion-dev/remotion · error · TypeError

" " must be

Error message

"${name}" must be ${formatEnum(variants)}

What it means

TypeError thrown by halftone-linear-gradient's assertOptionalEnum (halftone-linear-gradient.ts:162) when colorMode is provided but is not one of the allowed variants. Allowed variants are HALFTONE_LINEAR_GRADIENT_COLOR_MODES ('solid' or 'source'). The message lists the valid choices via formatEnum.

Solutions

  1. Set colorMode to 'solid' (use dotColor) or 'source' (sample source colors).
  2. If accepting user input, narrow it before passing: ['solid','source'].includes(v) ? v : 'solid'.
  3. Check the effect's docs/types for the current enum after upgrading @remotion/effects.

Example fix

// before
<halftoneLinearGradient colorMode="colored" />
// -> "colorMode" must be "solid" or "source"

// after
<halftoneLinearGradient colorMode="solid" dotColor="#ff00aa" />
Defensive patterns

Strategy: type-guard

Validate before calling

const COLOR_MODES = ['solid', 'source'] as const;
type ColorMode = typeof COLOR_MODES[number];
const normalizeColorMode = (v: unknown): ColorMode =>
  COLOR_MODES.includes(v as ColorMode) ? (v as ColorMode) : 'solid';

Type guard

const isColorMode = (v: unknown): v is 'solid' | 'source' =>
  v === 'solid' || v === 'source';

Try / catch

null

Prevention

When it happens

Trigger: validateHalftoneLinearGradientParams calls assertOptionalEnum(params.colorMode, 'colorMode', HALFTONE_LINEAR_GRADIENT_COLOR_MODES) (line 234). Triggered by passing colorMode: 'custom', colorMode: '', or any string other than 'solid'/'source'. A non-string colorMode (e.g. a number) also triggers.

Common situations: Typo in colorMode; copying a value from a different effect's API; passing a value derived from user input without narrowing; assuming an enum that no longer matches after a version upgrade.

Related errors


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

Appendix: source

Thrown at packages/effects/src/halftone-linear-gradient.ts:172

	}

	return `${variants
		.slice(0, -1)
		.map((variant) => `"${variant}"`)
		.join(', ')} or "${variants[variants.length - 1]}"`;
};

const assertOptionalEnum = <T extends string>(
	value: unknown,
	name: string,
	variants: readonly T[],
): void => {
	if (value === undefined) {
		return;
	}

	if (typeof value !== 'string' || !variants.includes(value as T)) {
		throw new TypeError(`"${name}" must be ${formatEnum(variants)}`);
	}
};

const resolve = (
	p: HalftoneLinearGradientParams,
): HalftoneLinearGradientResolved => ({
	firstStopDotSize: p.firstStopDotSize ?? DEFAULT_FIRST_STOP_DOT_SIZE,
	secondStopDotSize: p.secondStopDotSize ?? DEFAULT_SECOND_STOP_DOT_SIZE,
	firstStopPosition: [
		...(p.firstStopPosition ?? DEFAULT_FIRST_STOP_POSITION),
	] as UvCoordinate,
	secondStopPosition: [
		...(p.secondStopPosition ?? DEFAULT_SECOND_STOP_POSITION),
	] as UvCoordinate,
	gridSize: p.gridSize ?? DEFAULT_GRID_SIZE,
	colorMode: p.colorMode ?? 'solid',
	dotColor:
		'dotColor' in p ? (p.dotColor ?? DEFAULT_DOT_COLOR) : DEFAULT_DOT_COLOR,

View on GitHub (pinned to 78fe4bb3fd)