remotion-dev/remotion · error · Error

"fps" must be a number, but you passed a value of type ${typ

Error message

"fps" must be a number, but you passed a value of type ${typeof fps} ${location}

What it means

Remotion validates the `fps` value of a composition or video config via `validateFps()` before it is used. This specific branch fires when the value passed as `fps` is not of type `number` (e.g. a string from CLI parsing, `undefined`, or `null`). The `${location}` placeholder in the message is filled with a human-readable hint of where the bad value originated (e.g. the composition id or 'the `fps` prop').

Source

Thrown at packages/core/src/validation/validate-fps.ts:7

export function validateFps(
	fps: unknown,
	location: string,
	isGif: boolean,
): asserts fps is number {
	if (typeof fps !== 'number') {
		throw new Error(
			`"fps" must be a number, but you passed a value of type ${typeof fps} ${location}`,
		);
	}

	if (!Number.isFinite(fps)) {
		throw new Error(
			`"fps" must be a finite, but you passed ${fps} ${location}`,
		);
	}

	if (isNaN(fps)) {
		throw new Error(`"fps" must not be NaN, but got ${fps} ${location}`);
	}

	if (fps <= 0) {
		throw new TypeError(`"fps" must be positive, but got ${fps} ${location}`);
	}

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Ensure `fps` is a literal number, e.g. `fps={30}`.
  2. If loading fps from env/JSON, coerce explicitly: `fps={Number(process.env.REMOTION_FPS)}`.
  3. Add a runtime guard before constructing the composition: `if (typeof fps !== 'number') throw ...`.
  4. Check the `${location}` segment of the error to find which composition or prop is at fault.

Example fix

// before
<Composition fps="30" ... />
// after
<Composition fps={30} ... />
Defensive patterns

Strategy: validation

Validate before calling

function assertFps(fps: unknown, location: string): void {
  if (typeof fps !== 'number') {
    throw new Error(`Invalid fps at ${location}: expected number, got ${typeof fps}`);
  }
}
assertFps(myFps, 'my-comp');

Type guard

const isNumber = (v: unknown): v is number => typeof v === 'number';

Prevention

When it happens

Trigger: Passing `fps` as a non-number to a `<Composition fps={...}>`, `useVideoConfig()`, `resolveVideoConfig()`, or any config-building call that routes through `validateFps`. Typical offenders: `fps="30"` (string), `fps={null}`, `fps={undefined}`, or a value read from a JSON/env file that was not coerced.

Common situations: Reading fps from an environment variable or JSON config file (always strings), deserializing a composition config from a server payload, or passing a CSS-unit string like `"30fps"`.

Related errors


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