remotion-dev/remotion · error · TypeError
"${name}" must be greater than -${MAX_ABSOLUTE_ANGLE} and le
Error message
"${name}" must be greater than -${MAX_ABSOLUTE_ANGLE} and less than ${MAX_ABSOLUTE_ANGLE}, but got ${JSON.stringify(value)} What it means
The skew() effect's validateAngle helper checks that both x and y skew angles have an absolute value strictly less than MAX_ABSOLUTE_ANGLE (89 degrees). A skew angle of exactly ±89 or greater is rejected because tan() approaches infinity at ±90°, which would produce a degenerate or undefined transformation matrix.
Source
Thrown at packages/effects/src/skew.ts:100
!Array.isArray(value) ||
value.length !== 2 ||
value.some((item) => typeof item !== 'number' || !Number.isFinite(item))
) {
throw new TypeError(`"${name}" must be a [number, number] tuple`);
}
};
const validateUvCoordinate = (value: number, name: string): void => {
if (value < 0 || value > 1) {
throw new TypeError(
`"${name}" must be between 0 and 1, but got ${JSON.stringify(value)}`,
);
}
};
const validateAngle = (value: number, name: string): void => {
if (Math.abs(value) >= MAX_ABSOLUTE_ANGLE) {
throw new TypeError(
`"${name}" must be greater than -${MAX_ABSOLUTE_ANGLE} and less than ${MAX_ABSOLUTE_ANGLE}, but got ${JSON.stringify(value)}`,
);
}
};
const validateSkewParams = (params: SkewParams): void => {
assertEffectParamsObject(params, 'Skew');
assertOptionalFiniteNumber(params.x, 'x');
assertOptionalFiniteNumber(params.y, 'y');
assertOptionalUvCoordinate(params.origin, 'origin');
const resolved = resolve(params);
validateAngle(resolved.x, 'x');
validateAngle(resolved.y, 'y');
validateUvCoordinate(resolved.origin[0], 'origin[0]');
validateUvCoordinate(resolved.origin[1], 'origin[1]');
};
const SKEW_VS = /* glsl */ `#version 300 esView on GitHub (pinned to 78fe4bb3fd)
Solutions
- Keep both x and y skew angles strictly between -89 and 89 degrees (exclusive).
- If animating, clamp the interpolated value: Math.min(88, Math.max(-88, value)) or use a smaller range.
- Ensure you are passing degrees, not radians — the effect expects degrees and converts internally.
- Note the Studio schema caps at ±80, but the hard limit is ±89 — stay within ±80 for safety.
Example fix
// before — angle at exactly 89 degrees, hits the boundary
skew({ x: 89, y: 0 })
// before — angle in radians mistaken for degrees
skew({ x: 1.4, y: 0 }) // 1.4 radians ≈ 80 degrees, works but unintended
// after — safe value within the open interval (-89, 89)
skew({ x: 45, y: 0 })
// after — clamp animated values
skew({ x: Math.min(80, Math.max(-80, animatedValue)), y: 0 }) Defensive patterns
Strategy: validation
Validate before calling
// Validate and clamp skew angles to the valid range before calling skew
const MAX_SAFE_SKEW = 88; // stay below the 89-degree hard limit
function clampSkewAngle(value: number): number {
return Math.min(MAX_SAFE_SKEW, Math.max(-MAX_SAFE_SKEW, value));
}
// Or validate strictly:
function assertValidAngle(value: number, name: string): void {
if (Math.abs(value) >= 89) {
throw new Error(`${name} must be strictly between -89 and 89 degrees, got ${value}`);
}
}
assertValidAngle(rawX, 'x');
skew({ x: rawX, y: 0 }); Type guard
const isValidSkewAngle = (v: unknown): v is number =>
typeof v === 'number' && Number.isFinite(v) && Math.abs(v) < 89;
// Usage:
const x: unknown = userInput;
if (isValidSkewAngle(x)) {
skew({ x, y: 0 });
} else {
// handle invalid angle
} Try / catch
try {
skew({ x: rawX, y: 0 });
} catch (e) {
if (e instanceof TypeError && e.message.includes('greater than -89')) {
// Clamp to safe range and retry
const safeX = Math.min(80, Math.max(-80, rawX));
skew({ x: safeX, y: 0 });
} else {
throw e;
}
} Prevention
- Keep skew angles strictly between -89 and 89 degrees (exclusive boundary).
- Pass angles in degrees, not radians — the effect converts internally.
- Clamp animated values to a safe range like ±80 to stay well within limits.
- The Studio schema caps at ±80 — use that as your practical maximum.
When it happens
Trigger: Calling skew({ x: 89 }) (exactly at the boundary), skew({ x: 90 }) (tan(90°) is infinite), skew({ x: -89 }) (negative boundary), skew({ y: 100 }) (beyond 89°), or skew({ x: 89, y: 89 }) (both at the limit). The check is Math.abs(value) >= 89, so exactly 89 is rejected — values must be in the open interval (-89, 89).
Common situations: Animating skew angle with an interpolation that reaches or exceeds ±89; passing an angle in radians instead of degrees (e.g., 1.57 ≈ 90° but passed as if degrees); confusing the schema UI limits (±80 in Studio) with the hard-coded MAX_ABSOLUTE_ANGLE (89); extreme user-configured values from a slider or input field.
Related errors
- "${name}" must be a [number, number] tuple
- "${name}" must be between 0 and 1, but got ${JSON.stringify(
- "${name}" must be greater than 0, but got ${JSON.stringify(v
- Starburst effect requires a parameters object, but got ${JSO
- "rays" must be a finite number, but got ${JSON.stringify(ray
AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12).
Data as JSON: /api/errors/3cfed6257ce129b8.
Report an issue: GitHub.