remotion-dev/remotion · error · TypeError
'expiresIn' should be finite but is ${presignExpiration}
Error message
'expiresIn' should be finite but is ${presignExpiration} What it means
Thrown by validatePresignExpiration() when expiresIn is a number, not NaN, but not finite (Infinity or -Infinity). AWS limits presigned URL lifetimes to a maximum of 604800 seconds (7 days); an infinite TTL is impossible.
Source
Thrown at packages/lambda-client/src/validate-presign-expiration.ts:22
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(
`The 'expiresIn' parameter must be less or equal than ${MAX_PRESIGN_EXPIRATION} (7 days) as enforced by AWS`,
);
}
View on GitHub (pinned to 78fe4bb3fd)
Solutions
- Clamp the value with Math.min(value, 604800) and reject -Infinity / negative values up front.
- Use Number.isFinite() and fall back to undefined if the input is non-finite.
- Audit the formula generating expiresIn for divisions by zero.
Example fix
// before
const expiresIn = totalSeconds / 0; // Infinity
await renderMediaOnLambda({..., opts: {expiresIn}});
// after
const raw = totalSeconds / divisor;
const expiresIn = Number.isFinite(raw) ? Math.min(raw, 604800) : undefined;
await renderMediaOnLambda({..., opts: {expiresIn}}); Defensive patterns
Strategy: validation
Validate before calling
const raw = Number(input); const expiresIn = Number.isFinite(raw) ? Math.min(raw, 604800) : undefined;
Type guard
const isFiniteExpiresIn = (v: unknown): v is number => typeof v === 'number' && Number.isFinite(v);
Prevention
- Reject 'Infinity' literals at the parsing layer.
- Clamp computed TTLs against the 604800 ceiling.
- Audit divisions in TTL formulas for zero divisors.
When it happens
Trigger: Passing expiresIn: Number('Infinity'), parseFloat('Infinity'), or any computation that overflows to Infinity (e.g. division by zero).
Common situations: A config field accepting the literal 'Infinity'; a formula like maxValue / count where count is zero.
Related errors
- 'expiresIn' should be a number, but is ${JSON.stringify(pres
- 'expiresIn' should not be NaN, but is NaN
- 'expiresIn' should be an integer but is ${JSON.stringify(pre
- maxRetries must be a number, but is ${JSON.stringify(maxRetr
- maxRetries must be finite, but is ${maxRetries}
AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12).
Data as JSON: /api/errors/444e72f32a2498b5.
Report an issue: GitHub.