{"record":{"id":"5e58dbf9b86fa160","repo":"swc-project/swc","slug":"expected-identifier-value","errorCode":null,"errorMessage":"Expected identifier value","messagePattern":"Expected identifier value","errorType":"validation","errorClass":"swc_css_parser::error::Error","httpStatus":null,"severity":"error","filePath":"crates/swc_css_parser/src/parser/at_rules/mod.rs","lineNumber":1733,"sourceCode":"                    span: span!(self, span.lo),\n                    name,\n                }));\n            }\n            _ => {}\n        };\n\n        let left = self.parse()?;\n\n        self.input.skip_ws();\n\n        match cur!(self) {\n            tok!(\")\") => {\n                bump!(self);\n\n                let name = match left {\n                    MediaFeatureValue::Ident(ident) => MediaFeatureName::Ident(ident),\n                    _ => {\n                        return Err(Error::new(span, ErrorKind::Expected(\"identifier value\")));\n                    }\n                };\n\n                Ok(MediaFeature::Boolean(MediaFeatureBoolean {\n                    span: span!(self, span.lo),\n                    name,\n                }))\n            }\n            tok!(\":\") => {\n                bump!(self);\n\n                self.input.skip_ws();\n\n                let name = match left {\n                    MediaFeatureValue::Ident(ident) => MediaFeatureName::Ident(ident),\n                    _ => {\n                        return Err(Error::new(span, ErrorKind::Expected(\"identifier value\")));\n                    }","sourceCodeStart":1715,"sourceCodeEnd":1751,"githubUrl":"https://github.com/swc-project/swc/blob/5176682b65416c6b5de6b47379ae1588ea3ecb3f/crates/swc_css_parser/src/parser/at_rules/mod.rs#L1715-L1751","documentation":"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.","triggerScenarios":"'@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.","commonSituations":"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.","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"],"exampleFix":"/* before */\n@media (200px) {\n  .a { color: red; }\n}\n\n/* after */\n@media (width >= 200px) {\n  .a { color: red; }\n}","handlingStrategy":"validation","validationCode":"fn boolean_features_ok(css: &str) -> bool {\n    // best-effort: every parenthesized (...) with no ':' and no comparison must be a bare ident\n    let bytes = css.as_bytes();\n    let mut i = 0;\n    while let Some(open) = css[i..].find('(') {\n        let start = i + open;\n        if let Some(close_rel) = css[start + 1..].find(')') {\n            let inner = &css[start + 1..start + 1 + close_rel];\n            let has_op = [\":\", \"<\", \">\"].iter().any(|o| inner.contains(o));\n            if !has_op && !inner.starts_with(\"--\") {\n                let ok = inner.chars().all(|c| c.is_alphanumeric() || c == '-' || c == '_');\n                if !ok || inner.parse::<f64>().is_ok() {\n                    return false;\n                }\n            }\n            i = start + 1 + close_rel;\n        } else {\n            break;\n        }\n        let _ = bytes;\n    }\n    true\n}","typeGuard":"fn is_identifier_value_error(e: &swc_css_parser::error::Error) -> bool {\n    matches!(e.kind(), swc_css_parser::error::ErrorKind::Expected(m) if *m == \"identifier value\")\n}","tryCatchPattern":"match parse_file::<Stylesheet>(&fm, None, config, &mut errors) {\n    Ok(sheet) => handle(sheet),\n    Err(err) if is_identifier_value_error(&err) => {\n        let (span, _) = *err.into_inner();\n        hint_at_span(css, span, \"boolean media features need a name like (width), not a value; use (width >= N) for comparisons\");\n    }\n    Err(err) => return Err(err.into()),\n}","preventionTips":["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"],"tags":["css","swc","parser","at-rules","media-query","media-feature","syntax"],"backgroundTag":"css-media-feature-syntax","analyzedSha":"5176682b65416c6b5de6b47379ae1588ea3ecb3f","analyzedAt":"2026-08-17T16:16:52.067Z","contentChangedAt":"2026-08-17T16:16:52.067Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}