swc-project/swc · error · swc_css_parser::error::Error
Expected identifier value
Error message
Expected identifier value
What it means
Thrown while parsing a boolean media feature — the form '(name)' with no colon or comparison. After parsing the single value inside the parentheses the parser sees ')' and requires that value to have been an identifier (the feature name). If it parsed as a number, dimension, or function instead, ErrorKind::Expected("identifier value") is raised with the span of the opening parenthesis.
Source
Thrown at crates/swc_css_parser/src/parser/at_rules/mod.rs:1733
span: span!(self, span.lo),
name,
}));
}
_ => {}
};
let left = self.parse()?;
self.input.skip_ws();
match cur!(self) {
tok!(")") => {
bump!(self);
let name = match left {
MediaFeatureValue::Ident(ident) => MediaFeatureName::Ident(ident),
_ => {
return Err(Error::new(span, ErrorKind::Expected("identifier value")));
}
};
Ok(MediaFeature::Boolean(MediaFeatureBoolean {
span: span!(self, span.lo),
name,
}))
}
tok!(":") => {
bump!(self);
self.input.skip_ws();
let name = match left {
MediaFeatureValue::Ident(ident) => MediaFeatureName::Ident(ident),
_ => {
return Err(Error::new(span, ErrorKind::Expected("identifier value")));
}View on GitHub (pinned to 5176682b65)
Solutions
- Name the feature in boolean context: @media (hover), @media (width)
- Use range syntax for value comparisons: @media (width >= 200px)
- Use the classic plain form: @media (min-width: 200px)
- Remember custom '--*' features are only valid in boolean context and still need the leading ident
Example fix
/* before */
@media (200px) {
.a { color: red; }
}
/* after */
@media (width >= 200px) {
.a { color: red; }
} Defensive patterns
Strategy: validation
Validate before calling
fn boolean_features_ok(css: &str) -> bool {
// best-effort: every parenthesized (...) with no ':' and no comparison must be a bare ident
let bytes = css.as_bytes();
let mut i = 0;
while let Some(open) = css[i..].find('(') {
let start = i + open;
if let Some(close_rel) = css[start + 1..].find(')') {
let inner = &css[start + 1..start + 1 + close_rel];
let has_op = [":", "<", ">"].iter().any(|o| inner.contains(o));
if !has_op && !inner.starts_with("--") {
let ok = inner.chars().all(|c| c.is_alphanumeric() || c == '-' || c == '_');
if !ok || inner.parse::<f64>().is_ok() {
return false;
}
}
i = start + 1 + close_rel;
} else {
break;
}
let _ = bytes;
}
true
} Type guard
fn is_identifier_value_error(e: &swc_css_parser::error::Error) -> bool {
matches!(e.kind(), swc_css_parser::error::ErrorKind::Expected(m) if *m == "identifier value")
} Try / catch
match parse_file::<Stylesheet>(&fm, None, config, &mut errors) {
Ok(sheet) => handle(sheet),
Err(err) if is_identifier_value_error(&err) => {
let (span, _) = *err.into_inner();
hint_at_span(css, span, "boolean media features need a name like (width), not a value; use (width >= N) for comparisons");
}
Err(err) => return Err(err.into()),
} Prevention
- Never emit a bare value inside media parentheses
- Prefer range syntax when only a size is known
- Serialize sizes from code as numbers, not quoted strings
- Add a stylelint step with media-feature-name-no-unknown
When it happens
Trigger: '@media (200px)' (a length where a feature name belongs), '@media (calc(10px + 2em))' (math function as a boolean feature), '@media (5)' — any boolean-context paren whose content is not a plain ident.
Common situations: Authors writing value-only shorthand expecting it to mean min-width, CSS generated from design tokens that interpolates raw sizes, and copy-paste of range syntax with the comparison operator accidentally removed.
Related errors
- Expected '>' or '<' operators
- Expected number, ident, dimension or function token
- Expected ident (exclude the keywords 'only', 'not', 'and', '
- Expected left comparison operator should be equal right comp
- Expected function or '('
AI-assisted analysis of swc-project/swc@5176682b65 (2026-08-17).
Data as JSON: /api/errors/5e58dbf9b86fa160.
Report an issue: GitHub.