swc-project/swc · error · Error
Expected 'deg', 'grad', 'rad' or 'turn' units
Error message
Expected 'deg', 'grad', 'rad' or 'turn' units
What it means
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.
Source
Thrown at crates/swc_css_parser/src/parser/values_and_units/mod.rs:2069
if !is!(self, Dimension) {
return Err(Error::new(span, ErrorKind::Expected("dimension token")));
}
match bump!(self) {
Token::Dimension {
dimension: dimension_token,
} => {
let DimensionToken {
value,
unit,
raw_value,
raw_unit,
..
} = *dimension_token;
if !is_angle_unit(&unit) {
return Err(Error::new(
span,
ErrorKind::Expected("'deg', 'grad', 'rad' or 'turn' units"),
));
}
let unit_len = raw_unit.len() as u32;
Ok(Angle {
span,
value: Number {
span: Span::new(span.lo, span.hi - BytePos(unit_len)),
value,
raw: Some(raw_value),
},
unit: Ident {
span: Span::new(span.hi - BytePos(unit_len), span.hi),
value: unit,
raw: Some(raw_unit),View on GitHub (pinned to 5176682b65)
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.
Example fix
/* before */
a { transform: rotate(90segs); }
/* after */
a { transform: rotate(90deg); } Defensive patterns
Strategy: validation
Validate before calling
const ANGLE_UNITS = new Set(["deg", "grad", "rad", "turn"]);
function hasValidAngleUnit(v: string): boolean {
const i = [...v].findIndex(c => /[a-zA-Z]/.test(c));
return i > 0 && ANGLE_UNITS.has(v.slice(i).toLowerCase());
} Type guard
fn valid_angle_unit(unit: &str) -> bool {
matches!(unit.to_ascii_lowercase().as_str(), "deg" | "grad" | "rad" | "turn")
} Try / catch
use swc_css_parser::error::ErrorKind;
if let Err(e) = parse_input::<Stylesheet>(src, opts) {
if matches!(e.kind(), ErrorKind::Expected("'deg', 'grad', 'rad' or 'turn' units")) {
// unit typo: report span and reject the sheet rather than guessing a conversion
return Err(format!("bad angle unit at {:?}", e.span()).into());
}
return Err(e.into());
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Expected 's' or 'ms' units
- Expected 'Hz' or 'kHz' units
- Expected 'dpi', 'dpcm', 'dppx' or 'x' units
- Expected 'fr' unit
- Expected function or '('
AI-assisted analysis of swc-project/swc@5176682b65 (2026-08-17).
Data as JSON: /api/errors/b0100e9cfeb71351.
Report an issue: GitHub.