swc-project/swc · error · swc_css_parser::error::Error
Expected '>' or '<' operators
Error message
Expected '>' or '<' operators
What it means
Thrown while parsing media range syntax '(400px <= width)'. After the left value the parser accepts only '<' optionally followed by '=', or '>' optionally followed by '=' — i.e. <, <=, >, >=. Any other token at the comparison position raises ErrorKind::Expected("'>' or '<' operators").
Source
Thrown at crates/swc_css_parser/src/parser/at_rules/mod.rs:1818
}
let right_comparison = match bump!(self) {
tok!("<") => {
if eat!(self, "=") {
MediaFeatureRangeComparison::Le
} else {
MediaFeatureRangeComparison::Lt
}
}
tok!(">") => {
if eat!(self, "=") {
MediaFeatureRangeComparison::Ge
} else {
MediaFeatureRangeComparison::Gt
}
}
_ => {
return Err(Error::new(
span,
ErrorKind::Expected("'>' or '<' operators"),
));
}
};
self.input.skip_ws();
let right = self.parse()?;
self.input.skip_ws();
expect!(self, ")");
let name = match center {
MediaFeatureValue::Ident(ident) => MediaFeatureName::Ident(ident),
_ => {
return Err(Error::new(span, ErrorKind::Expected("identifier value")));View on GitHub (pinned to 5176682b65)
Solutions
- Use one of the four allowed operators: <, <=, >, >=
- For 'at least' semantics write @media (min-width: 600px) or @media (width >= 600px)
- If you generate queries, whitelist the operator set before emitting
Example fix
/* before */
@media (width = 600px) { }
/* after */
@media (width >= 600px) { } Defensive patterns
Strategy: validation
Validate before calling
const OPS: [&str; 4] = ["<", "<=", ">", ">="];
fn range_operators_ok(css: &str) -> bool {
for cap in css.split('(').skip(1) {
let inner = cap.split(')').next().unwrap_or("");
if inner.contains(':') {
continue;
}
for tok in inner.split_whitespace() {
if ["<", ">", "<=", ">="].contains(&tok.as_str()) {
continue;
}
if tok.starts_with('=') || tok.contains("==") || tok.contains('~') {
return false;
}
}
}
let _ = OPS;
true
} Type guard
fn is_range_operator_error(e: &swc_css_parser::error::Error) -> bool {
matches!(e.kind(), swc_css_parser::error::ErrorKind::Expected(m) if *m == "'>' or '<' operators")
} Try / catch
match parse_file::<Stylesheet>(&fm, None, config, &mut errors) {
Ok(sheet) => handle(sheet),
Err(err) if is_range_operator_error(&err) => {
let (span, _) = *err.into_inner();
hint_at_span(css, span, "media range syntax allows only < <= > >=; there is no '=' operator");
}
Err(err) => return Err(err.into()),
} Prevention
- Whitelist comparison operators in query generators to {<, <=, >, >=}
- Do not reuse JS comparison strings for CSS
- Keep legacy (min-width: N) and range syntax in separate code paths
- Lint sources for '==' inside @media conditions
When it happens
Trigger: '@media (width = 600px)' (single equals, which the media grammar does not have), '@media (width == 600px)', '@media (width ~ 600px)', '@media (width => 600px)'.
Common situations: Authors carrying '=' over from JS or from container queries in older draft syntax, transpilers/rewriters that normalize ':' to '=', and typos in hand-written level-4 range syntax.
Related errors
- Expected identifier value
- Expected left comparison operator should be equal right comp
- Expected number, ident, dimension or function token
- Expected ident (exclude the keywords 'only', 'not', 'and', '
- Expected function or '('
AI-assisted analysis of swc-project/swc@5176682b65 (2026-08-17).
Data as JSON: /api/errors/a4d3665726345345.
Report an issue: GitHub.