{"record":{"id":"d0ed95d8471114de","repo":"swc-project/swc","slug":"expected-id-class-attribute-or-pseudo-class-sele","errorCode":null,"errorMessage":"Expected id, class, attribute or pseudo-class selector","messagePattern":"Expected id, class, attribute or pseudo-class selector","errorType":"validation","errorClass":"swc_css_parser::error::Error","httpStatus":null,"severity":"error","filePath":"crates/swc_css_parser/src/parser/selectors/mod.rs","lineNumber":611,"sourceCode":"            value,\n        })\n    }\n}\n\nimpl<I> Parse<SubclassSelector> for Parser<I>\nwhere\n    I: ParserInput,\n{\n    fn parse(&mut self) -> PResult<SubclassSelector> {\n        match cur!(self) {\n            tok!(\"#\") => Ok(SubclassSelector::Id(self.parse()?)),\n            tok!(\".\") => Ok(SubclassSelector::Class(self.parse()?)),\n            tok!(\"[\") => Ok(SubclassSelector::Attribute(self.parse()?)),\n            tok!(\":\") => Ok(SubclassSelector::PseudoClass(self.parse()?)),\n            _ => {\n                let span = self.input.cur_span();\n\n                return Err(Error::new(\n                    span,\n                    ErrorKind::Expected(\"id, class, attribute or pseudo-class selector\"),\n                ));\n            }\n        }\n    }\n}\n\nimpl<I> Parse<IdSelector> for Parser<I>\nwhere\n    I: ParserInput,\n{\n    fn parse(&mut self) -> PResult<IdSelector> {\n        let span = self.input.cur_span();\n        let text = match bump!(self) {\n            Token::Hash {\n                is_id, value, raw, ..\n            } => {","sourceCodeStart":593,"sourceCodeEnd":629,"githubUrl":"https://github.com/swc-project/swc/blob/5176682b65416c6b5de6b47379ae1588ea3ecb3f/crates/swc_css_parser/src/parser/selectors/mod.rs#L593-L629","documentation":"A subclass selector is one of exactly four things: '#id', '.class', '[attr]', or ':pseudo-class'. The parser was asked to produce a SubclassSelector but the current token is none of '#', '.', '[', ':'. In the compound-selector loop this position is pre-checked, so seeing this error usually means a code path (pseudo-class arguments, re-parse of fragments, direct use of the Parse impl) reached a subclass position with an unexpected token.","triggerScenarios":"Selector fragments re-parsed against subclass grammar where the token is a combinator/delimiter, e.g. tooling that calls Parse::<SubclassSelector> on '> a', or malformed pseudo-class argument lists that route into subclass parsing with the cursor on the wrong token.","commonSituations":"Tools built on swc_css_parser that slice and re-parse selector fragments (linters, CSS modules, minifiers) with an off-by-one token position; rarely hand-authored CSS, since the guarded loop normally reports the friendlier InvalidSelector instead.","solutions":["If you maintain calling code: re-check token cursor positioning before invoking subclass parsing; ensure is!('#'/\".\"/'['/':') guards wrap the call","If hand CSS triggered it: look for a malformed pseudo-class or stray punctuation at the reported span and normalize the selector","Prefer parsing whole selectors rather than re-parsed fragments where possible"],"exampleFix":"/* before (fragment re-parse misuse) */\nparse_subclass(\"> a\")\n/* after */\nparse_selector(\"> a\")  // parse at the right grammar level, or guard on the first token","handlingStrategy":"type-guard","validationCode":"// Only attempt subclass parsing when the token is one of the four openers\nconst subclassOpeners = new Set(['#', '.', '[', ':']);\nfunction isSubclassStart(tok) { return subclassOpeners.has(tok); }","typeGuard":"// Rust\nfn is_subclass_start(t: &Token) -> bool {\n  matches!(t, Token::Hash { .. } | Token::Delim { value: '.' | '[' | ':' | '#', .. })\n}","tryCatchPattern":"// Rust: guard the call instead of relying on the error\nif is_subclass_start(&cur) { let sel: SubclassSelector = parser.parse()?; } else { /* different grammar production */ }","preventionTips":["In tooling, always pair Parse::<SubclassSelector> with a token-kind check","Parse selectors at the grammar level they belong to; do not re-parse fragments against a narrower production"],"tags":["css","selector","subclass","syntax"],"backgroundTag":"css-selector-syntax-error","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"}