remotion-dev/remotion · error · TypeError

"${name}" must be a boolean, but got ${JSON.stringify(value)

Error message

"${name}" must be a boolean, but got ${JSON.stringify(value)}

What it means

Thrown by the dot-grid effect's assertOptionalBoolean guard when the invert prop is supplied but is not a boolean. invert toggles whether dots become holes versus filled circles in the fragment shader, and because it is uploaded to a bool uniform, the runtime demands an actual boolean. Truthy/falsy values like 'true', 1, 0, or null are rejected.

Source

Thrown at packages/effects/src/dot-grid.ts:65

type DotGridResolved = {
	dotSize: number;
	gridSize: number;
	invert: boolean;
};

const resolve = (p: DotGridParams): DotGridResolved => ({
	dotSize: p.dotSize ?? DEFAULT_DOT_SIZE,
	gridSize: p.gridSize ?? DEFAULT_GRID_SIZE,
	invert: p.invert ?? DEFAULT_INVERT,
});

const assertOptionalBoolean = (value: unknown, name: string): void => {
	if (value === undefined) {
		return;
	}

	if (typeof value !== 'boolean') {
		throw new TypeError(
			`"${name}" must be a boolean, but got ${JSON.stringify(value)}`,
		);
	}
};

const validatePositive = (value: number, name: string): void => {
	if (value <= 0) {
		throw new TypeError(
			`"${name}" must be greater than 0, but got ${JSON.stringify(value)}`,
		);
	}
};

const validateDotGridParams = (params: DotGridParams): void => {
	assertEffectParamsObject(params, 'Dot grid');
	assertOptionalFiniteNumber(params.dotSize, 'dotSize');
	assertOptionalFiniteNumber(params.gridSize, 'gridSize');
	assertOptionalBoolean(params.invert, 'invert');

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Pass a literal boolean: invert: true or invert: false.
  2. Coerce at the boundary: invert: String(raw) === 'true', or invert: Boolean(raw).
  3. If animating, drive invert from an interpolate() threshold that returns a boolean via a conditional, not a numeric spring value.
  4. Omit invert to accept the default (false).

Example fix

// before
dotGrid({invert: 'true', gridSize: 24});

// after
dotGrid({invert: String(process.env.INVERT) === 'true', gridSize: 24});
Defensive patterns

Strategy: type-guard

Validate before calling

const invert = raw == null ? undefined : String(raw) === 'true';
// then pass invert only when defined
dotGrid(invert === undefined ? {} : {invert});

Type guard

const isOptionalBoolean = (v: unknown): v is boolean | undefined =>
  v === undefined || typeof v === 'boolean';

const assertDotGridInvert = (v: unknown): boolean | undefined => {
  if (!isOptionalBoolean(v)) {
    throw new TypeError(`invert must be a boolean, got ${typeof v}`);
  }
  return v;
};

Prevention

When it happens

Trigger: Calling dotGrid() with invert: 'true' (string), invert: 1 or invert: 0 (number), invert: null, or invert: 'yes'. Also triggered by deserializing params from JSON where booleans were stored as 0/1 integers, or by binding invert to a schema that yields a string enum.

Common situations: Reading invert from a query string or env var (always strings); pulling config from YAML/TOML that coerces booleans; reusing a numeric toggle from another part of the app; animating invert with a Spring that interpolates to a fractional number.

Related errors


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