remotion-dev/remotion · error · TypeError

'expiresIn' should be an integer but is ${JSON.stringify(pre

Error message

'expiresIn' should be an integer but is ${JSON.stringify(presignExpiration)}

What it means

Thrown by validatePresignExpiration() when expiresIn is a finite number but not an integer. AWS presigned URL TTLs are measured in whole seconds; fractional seconds are not accepted by the signing logic.

Source

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

		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(
			`The 'expiresIn' parameter must be less or equal than ${MAX_PRESIGN_EXPIRATION} (7 days) as enforced by AWS`,
		);
	}

	if (presignExpiration < MIN_PRESIGN_EXPIRATION) {
		throw new TypeError(
			`The 'expiresIn' parameter must be greater or equal than ${MIN_PRESIGN_EXPIRATION}`,
		);
	}
};

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Round the value: Math.round(expiresIn).
  2. For unit conversions, round after multiplication to kill float drift.
  3. If accepting minutes/hours from users, convert to integer seconds explicitly.

Example fix

// before
const expiresIn = hours * 3600.5; // fractional
await renderMediaOnLambda({..., opts: {expiresIn}});

// after
const expiresIn = Math.round(hours * 3600);
await renderMediaOnLambda({..., opts: {expiresIn}});
Defensive patterns

Strategy: validation

Validate before calling

const expiresIn = Math.round(Number(input));

Type guard

const isIntegerExpiresIn = (v: unknown): v is number =>
  typeof v === 'number' && Number.isFinite(v) && v % 1 === 0;

Prevention

When it happens

Trigger: Passing expiresIn: 3600.5, or any value computed from a division that yields a decimal (e.g. minutes * 60.005).

Common situations: A UI that lets users enter fractional seconds; unit conversion that introduces floating-point error (hoursToSeconds = hours * 3600 producing 3599.9999).

Related errors


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