swc-project/swc · error · Error
Expected 's' or 'ms' units
Error message
Expected 's' or 'ms' units
What it means
Thrown by Parse<Time> in swc_css_parser when the token is a dimension but its unit is not a time unit. After bumping Token::Dimension it checks is_time_unit(&unit), which accepts only s and ms (ASCII case-insensitive). Units like sec, seconds, or misapplied units (px, hz) trigger this error with the span of the entire dimension token.
Source
Thrown at crates/swc_css_parser/src/parser/values_and_units/mod.rs:2122
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_time_unit(&unit) {
return Err(Error::new(span, ErrorKind::Expected("'s' or 'ms' units")));
}
let unit_len = raw_unit.len() as u32;
Ok(Time {
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
- Replace non-standard units: '1sec' -> '1s', '1500millis' -> '1500ms' or '1.5s'.
- Map friendly unit names to s/ms before generating CSS (second->s, millisecond->ms).
- Pre-validate with a whitelist of exactly s and ms.
Example fix
/* before */
a { animation-duration: 2sec; }
/* after */
a { animation-duration: 2s; } Defensive patterns
Strategy: validation
Validate before calling
const TIME_UNITS = new Set(["s", "ms"]);
function hasValidTimeUnit(v: string): boolean {
const i = [...v].findIndex(c => /[a-zA-Z]/.test(c));
return i > 0 && TIME_UNITS.has(v.slice(i).toLowerCase());
} Type guard
fn valid_time_unit(unit: &str) -> bool {
matches!(unit.to_ascii_lowercase().as_str(), "s" | "ms")
} Try / catch
use swc_css_parser::error::ErrorKind;
if let Err(e) = parse_input::<Stylesheet>(src, opts) {
if matches!(e.kind(), ErrorKind::Expected("'s' or 'ms' units")) {
return Err(format!("bad time unit at {:?}", e.span()).into());
}
return Err(e.into());
} Prevention
- Normalize friendly unit names (second/seconds/millis) to s/ms before emitting CSS.
- Keep a single unit constant for durations instead of accepting free-form strings.
- Unit-test the normalizer with common typos ('sec', 'second', 'MS').
When it happens
Trigger: Values like 'transition-duration: 1sec', 'animation: 500millis', 'duration: 30hz', or unit strings built from user input ('1' + 'econds'). Any dimension whose alphabetic tail is not exactly s or ms fails.
Common situations: Authors writing 'sec'/'seconds' out of habit, unit-configuration maps keyed by display names ('second') fed verbatim into generated CSS, and confusion between frequency and time units in audio/animation tooling.
Related errors
- Expected 'deg', 'grad', 'rad' or 'turn' 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/d130112c7dc3a811.
Report an issue: GitHub.