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
- Pass a literal boolean: invert: true or invert: false.
- Coerce at the boundary: invert: String(raw) === 'true', or invert: Boolean(raw).
- If animating, drive invert from an interpolate() threshold that returns a boolean via a conditional, not a numeric spring value.
- 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
- Coerce booleans at every external boundary (env vars, query strings, YAML/TOML) with Boolean(...) or String(x) === 'true'.
- Type the prop as boolean | undefined in your own wrappers so TypeScript rejects strings/numbers.
- Do not drive invert from a numeric Spring; derive a boolean via a threshold instead.
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
- "${name}" must be greater than 0, but got ${JSON.stringify(v
- "${name}" must be >= -1, but got ${JSON.stringify(value)}
- "${name}" must be greater than 0, but got ${JSON.stringify(v
- "${name}" must be a [number, number] tuple
- "${name}" must be a boolean, but got ${JSON.stringify(value)
AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12).
Data as JSON: /api/errors/08e247d9f0d1bdf7.
Report an issue: GitHub.