remotion-dev/remotion · error · TypeError

'expiresIn' should not be NaN, but is NaN

Error message

'expiresIn' should not be NaN, but is NaN

What it means

Thrown by validatePresignExpiration() when expiresIn is a number but equals NaN. Presigned URLs require a real TTL in seconds; AWS rejects NaN-derived signatures. The check runs after the typeof-number guard, so only a numeric NaN reaches it.

Source

Thrown at packages/lambda-client/src/validate-presign-expiration.ts:18

const MAX_PRESIGN_EXPIRATION = 604800;
const MIN_PRESIGN_EXPIRATION = 1;

export const validatePresignExpiration = (presignExpiration: unknown) => {
	if (typeof presignExpiration === 'undefined' || presignExpiration === null) {
		return;
	}

	if (typeof presignExpiration !== 'number') {
		throw new TypeError(
			`'expiresIn' should be a number, but is ${JSON.stringify(
				presignExpiration,
			)}`,
		);
	}

	if (Number.isNaN(presignExpiration)) {
		throw new TypeError(`'expiresIn' should not be NaN, but is NaN`);
	}

	if (!Number.isFinite(presignExpiration)) {
		throw new TypeError(
			`'expiresIn' should be finite but is ${presignExpiration}`,
		);
	}

	if (presignExpiration % 1 !== 0) {
		throw new TypeError(
			`'expiresIn' should be an integer but is ${JSON.stringify(
				presignExpiration,
			)}`,
		);
	}

	if (presignExpiration > MAX_PRESIGN_EXPIRATION) {
		throw new TypeError(

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Guard the parse with Number.isFinite() and fall back to undefined (let the library default) or a known good value.
  2. Validate the source string with /^\d+$/ before parseInt.
  3. Skip passing expiresIn when the input is missing rather than forwarding NaN.

Example fix

// before
const expiresIn = Number(process.env.EXPIRES_IN); // NaN
await renderMediaOnLambda({..., opts: {expiresIn}});

// after
const raw = Number(process.env.EXPIRES_IN);
const expiresIn = Number.isFinite(raw) ? raw : undefined;
await renderMediaOnLambda({..., opts: {expiresIn}});
Defensive patterns

Strategy: type-guard

Validate before calling

const raw = Number(process.env.EXPIRES_IN);
const expiresIn = Number.isFinite(raw) ? raw : undefined;

Type guard

const isValidExpiresIn = (v: unknown): v is number =>
  typeof v === 'number' && !Number.isNaN(v) && Number.isFinite(v);

Prevention

When it happens

Trigger: Passing expiresIn: Number(someUnsetVar) (NaN), expiresIn: parseInt('abc', 10) (NaN), or any arithmetic that yields NaN.

Common situations: Env-var parse where the variable is empty/non-numeric; a formula like (a - b) where both are undefined producing NaN.

Related errors


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