remotion-dev/remotion · error · TypeError

"dotSize" must be >= 1, but got ${JSON.stringify(params.dotS

Error message

"dotSize" must be >= 1, but got ${JSON.stringify(params.dotSize)}

What it means

Thrown by validateHalftoneParams() when params.dotSize is a finite number but less than 1. The halftone schema declares dotSize with min: 1, and this runtime guard enforces the same floor because sub-pixel dot sizes produce a degenerate grid. The message echoes the offending value via JSON.stringify so the bad input is visible.

Source

Thrown at packages/effects/src/halftone.ts:204

	assertOptionalEnum(params.colorMode, 'colorMode', HALFTONE_COLOR_MODES);
	if ('color' in params && params.color !== undefined) {
		throw new TypeError('"color" has been renamed to "dotColor"');
	}

	if (params.colorMode === 'source' && 'dotColor' in params) {
		throw new TypeError(
			'"dotColor" can only be set when "colorMode" is "solid"',
		);
	}

	assertOptionalColor(
		'dotColor' in params ? params.dotColor : undefined,
		'dotColor',
	);
	assertOptionalBoolean(params.invert, 'invert');

	if (params.dotSize !== undefined && params.dotSize < 1) {
		throw new TypeError(
			`"dotSize" must be >= 1, but got ${JSON.stringify(params.dotSize)}`,
		);
	}

	if (params.dotSpacing !== undefined && params.dotSpacing < 1) {
		throw new TypeError(
			`"dotSpacing" must be >= 1, but got ${JSON.stringify(params.dotSpacing)}`,
		);
	}
};

const HALFTONE_VS = /* glsl */ `#version 300 es
in vec2 aPos;
in vec2 aUv;
out vec2 vUv;
void main() {
	vUv = aUv;
	gl_Position = vec4(aPos, 0.0, 1.0);

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Clamp dotSize to at least 1: Math.max(1, value).
  2. Raise the minimum of any animation keyframe that targets dotSize to 1.
  3. If a slider drives dotSize, set its min attribute to 1.

Example fix

// before
halftone({ dotSize: frame < 10 ? frame * 0.3 : 20 })

// after
halftone({ dotSize: Math.max(1, frame < 10 ? frame * 0.3 : 20) })
Defensive patterns

Strategy: validation

Validate before calling

function clampDotSize(v: number | undefined): number | undefined {
  return v === undefined ? undefined : Math.max(1, v);
}
// then: halftone({ dotSize: clampDotSize(rawDotSize) })

Type guard

function isValidDotSize(v: unknown): v is number {
  return typeof v === 'number' && Number.isFinite(v) && v >= 1;
}

Prevention

When it happens

Trigger: Calling halftone({ dotSize: 0 }), halftone({ dotSize: 0.5 }), or halftone({ dotSize: -3 }). Passing NaN/Infinity is caught earlier by assertOptionalFiniteNumber, so this branch only fires for finite sub-1 numbers.

Common situations: Animation keyframes that ramp dotSize down to 0; math expressions like dotSize: width / 1000 that can collapse below 1 for small inputs; UI sliders without a lower bound.

Related errors


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