remotion-dev/remotion · warning · ErrorWithBacktrace
Odd rotation angle
Error message
Odd rotation angle
What it means
Thrown by get_rotation when the normalized rotation angle is not within 2 degrees of a multiple of 90. Remotion only supports orthogonal rotations; arbitrary angles indicate a malformed display matrix or unsupported rotation metadata.
Source
Thrown at packages/compositor/rust/rotation.rs:25
for bytes in value.chunks(4) {
let i32_value = i32::from_le_bytes(bytes.try_into().unwrap());
i32_values.push(i32_value);
}
if i32_values.len() != 9 {
Err(std::io::Error::new(ErrorKind::Other, "Invalid side data"))?;
}
return get_rotation(&i32_values);
}
pub fn get_rotation(displaymatrix: &[i32]) -> Result<f64, ErrorWithBacktrace> {
let mut theta = -(rotation_get(displaymatrix))?.round();
theta -= 360.0 * (theta / 360.0 + 0.9 / 360.0).floor();
if (theta - 90.0 * (theta / 90.0).round()).abs() > 2.0 {
Err(std::io::Error::new(ErrorKind::Other, "Odd rotation angle"))?;
}
return Ok(theta);
}
pub fn rotation_get(matrix: &[i32]) -> Result<f64, ErrorWithBacktrace> {
let scale0 = (matrix[0] as f64).hypot(matrix[3] as f64);
let scale1 = (matrix[1] as f64).hypot(matrix[4] as f64);
if scale0 == 0.0 || scale1 == 0.0 {
Err(std::io::Error::new(ErrorKind::Other, "Invalid matrix"))?;
}
let rotation = (((matrix[1] as f64) / scale1).atan2((matrix[0] as f64) / scale0)) * 180.0 / PI;
return Ok(-rotation);
}
View on GitHub (pinned to 78fe4bb3fd)
Solutions
- Strip the problematic rotation metadata on encode: `ffmpeg -i in.mp4 -metadata:s:v:0 rotate= -c copy out.mp4`.
- Re-encode the source so the display matrix is orthogonal or absent.
- If the angle is intended, pre-rotate the media to a clean 0/90/180/270 orientation outside Remotion.
Example fix
// before: source has a 17-degree display matrix -> throws // after: strip rotation metadata before importing // $ ffmpeg -i in.mp4 -metadata:s:v:0 rotate= -c copy out.mp4
Defensive patterns
Strategy: validation
Validate before calling
fn is_orthogonal(theta: f64) -> bool {
(theta - 90.0 * (theta / 90.0).round()).abs() <= 2.0
}
if !is_orthogonal(theta) { /* strip rotation metadata, treat as 0 */ } Type guard
null
Try / catch
let rot = match get_rotation(&matrix) {
Ok(r) => r,
Err(_) => 0.0,
}; Prevention
- Pre-rotate sources to a clean 0/90/180/270 orientation.
- Strip rotation metadata that encodes shear/skew.
- Validate matrix-derived angles before relying on them.
When it happens
Trigger: A display matrix that encodes a skew/non-orthogonal transform, or numeric corruption in the matrix entries producing a theta far from 0/90/180/270. The check `(theta - 90*round(theta/90)).abs() > 2.0` is the guard.
Common situations: Hand-edited or transcode-artifact display matrices; sources with perspective/shear encoded as rotation; rare codec/container bugs that write garbage into the display matrix.
Related errors
- Invalid side data
- Invalid matrix
- Not enough planes or linesizes
- No frame found at position {} for source {} (original source
- No audio stream found in '${input_path}'. Ensure the video c
AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12).
Data as JSON: /api/errors/00fabc44e918ccac.
Report an issue: GitHub.