{"record":{"id":"b0100e9cfeb71351","repo":"swc-project/swc","slug":"expected-deg-grad-rad-or-turn-units","errorCode":null,"errorMessage":"Expected 'deg', 'grad', 'rad' or 'turn' units","messagePattern":"Expected 'deg', 'grad', 'rad' or 'turn' units","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"crates/swc_css_parser/src/parser/values_and_units/mod.rs","lineNumber":2069,"sourceCode":"\n        if !is!(self, Dimension) {\n            return Err(Error::new(span, ErrorKind::Expected(\"dimension token\")));\n        }\n\n        match bump!(self) {\n            Token::Dimension {\n                dimension: dimension_token,\n            } => {\n                let DimensionToken {\n                    value,\n                    unit,\n                    raw_value,\n                    raw_unit,\n                    ..\n                } = *dimension_token;\n\n                if !is_angle_unit(&unit) {\n                    return Err(Error::new(\n                        span,\n                        ErrorKind::Expected(\"'deg', 'grad', 'rad' or 'turn' units\"),\n                    ));\n                }\n\n                let unit_len = raw_unit.len() as u32;\n\n                Ok(Angle {\n                    span,\n                    value: Number {\n                        span: Span::new(span.lo, span.hi - BytePos(unit_len)),\n                        value,\n                        raw: Some(raw_value),\n                    },\n                    unit: Ident {\n                        span: Span::new(span.hi - BytePos(unit_len), span.hi),\n                        value: unit,\n                        raw: Some(raw_unit),","sourceCodeStart":2051,"sourceCodeEnd":2087,"githubUrl":"https://github.com/swc-project/swc/blob/5176682b65416c6b5de6b47379ae1588ea3ecb3f/crates/swc_css_parser/src/parser/values_and_units/mod.rs#L2051-L2087","documentation":"Thrown by Parse<Angle> in swc_css_parser when the token IS a dimension but its unit is not a CSS angle unit. After bumping the Dimension token it checks is_angle_unit(&unit), which accepts only deg, grad, rad, turn (ASCII case-insensitive via matches_eq_ignore_ascii_case!). Any other unit attached to the number (px, s, em, invented units) produces this error with the span of the whole dimension token.","triggerScenarios":"Values like 'rotate(90segs)', 'rotate(100px)', 'transition-duration'-style values mistakenly used as angles, or '45degree'. Also reached via Parse<Hue>: 'hsl(30px 50% 50%)' passes the dimension check in Hue and then fails here because px is not an angle unit.","commonSituations":"Typos in angle units ('degree', 'degs'), confusion between animation duration ('s') and rotation angle ('deg') when generating CSS from JS, and data-driven CSS where a shared numeric suffix variable contains the wrong unit string.","solutions":["Use exactly deg, grad, rad, or turn as the unit (any casing; no plural forms).","Fix the source that generates the unit string (e.g. change a suffix constant from 'px'/'secs' to 'deg').","If the number is a plain hue in degrees, keep it a bare number ('hsl(120 50% 50%)') which Hue accepts without a unit.","Pre-validate with a unit whitelist before parsing."],"exampleFix":"/* before */\na { transform: rotate(90segs); }\n\n/* after */\na { transform: rotate(90deg); }","handlingStrategy":"validation","validationCode":"const ANGLE_UNITS = new Set([\"deg\", \"grad\", \"rad\", \"turn\"]);\nfunction hasValidAngleUnit(v: string): boolean {\n  const i = [...v].findIndex(c => /[a-zA-Z]/.test(c));\n  return i > 0 && ANGLE_UNITS.has(v.slice(i).toLowerCase());\n}","typeGuard":"fn valid_angle_unit(unit: &str) -> bool {\n    matches!(unit.to_ascii_lowercase().as_str(), \"deg\" | \"grad\" | \"rad\" | \"turn\")\n}","tryCatchPattern":"use swc_css_parser::error::ErrorKind;\nif let Err(e) = parse_input::<Stylesheet>(src, opts) {\n    if matches!(e.kind(), ErrorKind::Expected(\"'deg', 'grad', 'rad' or 'turn' units\")) {\n        // unit typo: report span and reject the sheet rather than guessing a conversion\n        return Err(format!(\"bad angle unit at {:?}\", e.span()).into());\n    }\n    return Err(e.into());\n}","preventionTips":["Whitelist angle units at the boundary where CSS is generated.","For hue positions prefer bare numbers (no unit) to sidestep unit checks entirely.","Add fixture tests for each angle unit in both lower and upper case."],"tags":["css","swc","parser","angle","units"],"backgroundTag":"css-invalid-angle-unit","analyzedSha":"5176682b65416c6b5de6b47379ae1588ea3ecb3f","analyzedAt":"2026-08-17T16:16:52.067Z","contentChangedAt":"2026-08-17T16:16:52.067Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}