{"record":{"id":"3cfed6257ce129b8","repo":"remotion-dev/remotion","slug":"name-must-be-greater-than-max-absolute-ang","errorCode":null,"errorMessage":"\"${name}\" must be greater than -${MAX_ABSOLUTE_ANGLE} and less than ${MAX_ABSOLUTE_ANGLE}, but got ${JSON.stringify(value)}","messagePattern":"\"(.+?)\" must be greater than -(.+?) and less than (.+?), but got (.+?)","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/effects/src/skew.ts","lineNumber":100,"sourceCode":"\t\t!Array.isArray(value) ||\n\t\tvalue.length !== 2 ||\n\t\tvalue.some((item) => typeof item !== 'number' || !Number.isFinite(item))\n\t) {\n\t\tthrow new TypeError(`\"${name}\" must be a [number, number] tuple`);\n\t}\n};\n\nconst validateUvCoordinate = (value: number, name: string): void => {\n\tif (value < 0 || value > 1) {\n\t\tthrow new TypeError(\n\t\t\t`\"${name}\" must be between 0 and 1, but got ${JSON.stringify(value)}`,\n\t\t);\n\t}\n};\n\nconst validateAngle = (value: number, name: string): void => {\n\tif (Math.abs(value) >= MAX_ABSOLUTE_ANGLE) {\n\t\tthrow new TypeError(\n\t\t\t`\"${name}\" must be greater than -${MAX_ABSOLUTE_ANGLE} and less than ${MAX_ABSOLUTE_ANGLE}, but got ${JSON.stringify(value)}`,\n\t\t);\n\t}\n};\n\nconst validateSkewParams = (params: SkewParams): void => {\n\tassertEffectParamsObject(params, 'Skew');\n\tassertOptionalFiniteNumber(params.x, 'x');\n\tassertOptionalFiniteNumber(params.y, 'y');\n\tassertOptionalUvCoordinate(params.origin, 'origin');\n\tconst resolved = resolve(params);\n\tvalidateAngle(resolved.x, 'x');\n\tvalidateAngle(resolved.y, 'y');\n\tvalidateUvCoordinate(resolved.origin[0], 'origin[0]');\n\tvalidateUvCoordinate(resolved.origin[1], 'origin[1]');\n};\n\nconst SKEW_VS = /* glsl */ `#version 300 es","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/effects/src/skew.ts#L82-L118","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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."],"exampleFix":"// before — angle at exactly 89 degrees, hits the boundary\nskew({ x: 89, y: 0 })\n// before — angle in radians mistaken for degrees\nskew({ x: 1.4, y: 0 })  // 1.4 radians ≈ 80 degrees, works but unintended\n\n// after — safe value within the open interval (-89, 89)\nskew({ x: 45, y: 0 })\n// after — clamp animated values\nskew({ x: Math.min(80, Math.max(-80, animatedValue)), y: 0 })","handlingStrategy":"validation","validationCode":"// Validate and clamp skew angles to the valid range before calling skew\nconst MAX_SAFE_SKEW = 88; // stay below the 89-degree hard limit\n\nfunction clampSkewAngle(value: number): number {\n  return Math.min(MAX_SAFE_SKEW, Math.max(-MAX_SAFE_SKEW, value));\n}\n\n// Or validate strictly:\nfunction assertValidAngle(value: number, name: string): void {\n  if (Math.abs(value) >= 89) {\n    throw new Error(`${name} must be strictly between -89 and 89 degrees, got ${value}`);\n  }\n}\n\nassertValidAngle(rawX, 'x');\nskew({ x: rawX, y: 0 });","typeGuard":"const isValidSkewAngle = (v: unknown): v is number =>\n  typeof v === 'number' && Number.isFinite(v) && Math.abs(v) < 89;\n\n// Usage:\nconst x: unknown = userInput;\nif (isValidSkewAngle(x)) {\n  skew({ x, y: 0 });\n} else {\n  // handle invalid angle\n}","tryCatchPattern":"try {\n  skew({ x: rawX, y: 0 });\n} catch (e) {\n  if (e instanceof TypeError && e.message.includes('greater than -89')) {\n    // Clamp to safe range and retry\n    const safeX = Math.min(80, Math.max(-80, rawX));\n    skew({ x: safeX, y: 0 });\n  } else {\n    throw e;\n  }\n}","preventionTips":["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."],"tags":["validation","typescript","skew","parameters","angle","math"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}