{"record":{"id":"3fde275ef5cfba23","repo":"swc-project/swc","slug":"expected-left-right-first-or-blank-ident","errorCode":null,"errorMessage":"Expected 'left', 'right', 'first' or 'blank' ident","messagePattern":"Expected 'left', 'right', 'first' or 'blank' ident","errorType":"validation","errorClass":"swc_css_parser::error::Error","httpStatus":null,"severity":"error","filePath":"crates/swc_css_parser/src/parser/at_rules/mod.rs","lineNumber":2041,"sourceCode":"    I: ParserInput,\n{\n    fn parse(&mut self) -> PResult<PageSelectorPseudo> {\n        let span = self.input.cur_span();\n\n        expect!(self, \":\");\n\n        let value = match cur!(self) {\n            Token::Ident { value, .. }\n                if matches_eq_ignore_ascii_case!(value, \"left\", \"right\", \"first\", \"blank\") =>\n            {\n                let name: Ident = self.parse()?;\n\n                name\n            }\n            _ => {\n                let span = self.input.cur_span();\n\n                return Err(Error::new(\n                    span,\n                    ErrorKind::Expected(\"'left', 'right', 'first' or 'blank' ident\"),\n                ));\n            }\n        };\n\n        Ok(PageSelectorPseudo {\n            span: span!(self, span.lo),\n            value,\n        })\n    }\n}\n\nimpl<I> Parse<LayerName> for Parser<I>\nwhere\n    I: ParserInput,\n{\n    fn parse(&mut self) -> PResult<LayerName> {","sourceCodeStart":2023,"sourceCodeEnd":2059,"githubUrl":"https://github.com/swc-project/swc/blob/5176682b65416c6b5de6b47379ae1588ea3ecb3f/crates/swc_css_parser/src/parser/at_rules/mod.rs#L2023-L2059","documentation":"Thrown while parsing a @page pseudo page selector. The CSS paged-media grammar allows only the four pseudo pages :left, :right, :first and :blank; when the ident after ':' is none of them (or the token is not an ident), ErrorKind::Expected(\"'left', 'right', 'first' or 'blank' ident\") is raised at that token.","triggerScenarios":"'@page :center { }', '@page :nth(2) { }', '@page :recto { }' — any pseudo not in the allowed set.","commonSituations":"Authors assuming nth() page selectors or writing custom pseudo names, print-stylesheet generators exposing arbitrary pseudo input, and porting drafts (recto/verso) that engines never shipped in this form.","solutions":["Use only @page :left, @page :right, @page :first, @page :blank","Use named pages for custom page setups: @page narrow { size: A5; } plus 'page: narrow' on elements","Drop unsupported pseudo pages before feeding print CSS to swc"],"exampleFix":"/* before */\n@page :center {\n  margin: 2cm;\n}\n\n/* after */\n@page {\n  margin: 2cm;\n}","handlingStrategy":"validation","validationCode":"const PAGE_PSEUDOS: [&str; 4] = [\"left\", \"right\", \"first\", \"blank\"];\n\nfn page_pseudos_ok(css: &str) -> bool {\n    for line in css.lines() {\n        let t = line.trim();\n        if t.starts_with(\"@page\") {\n            for part in t[5..].split_whitespace() {\n                let p = part.trim_matches(|c| c == ',' || c == '{' || c == '}');\n                if let Some(name) = p.strip_prefix(':') {\n                    if !PAGE_PSEUDOS.iter().any(|k| name.eq_ignore_ascii_case(k)) {\n                        return false;\n                    }\n                }\n            }\n        }\n    }\n    true\n}","typeGuard":"fn is_page_pseudo_error(e: &swc_css_parser::error::Error) -> bool {\n    matches!(e.kind(), swc_css_parser::error::ErrorKind::Expected(m) if *m == \"'left', 'right', 'first' or 'blank' ident\")\n}","tryCatchPattern":"match parse_file::<Stylesheet>(&fm, None, config, &mut errors) {\n    Ok(sheet) => handle(sheet),\n    Err(err) if is_page_pseudo_error(&err) => {\n        let (span, _) = *err.into_inner();\n        hint_at_span(css, span, \"@page accepts only :left, :right, :first, :blank — use named pages for custom setups\");\n    }\n    Err(err) => return Err(err.into()),\n}","preventionTips":["Restrict print stylesheet generators to the four legal pseudo pages","Use named pages (@page narrow {}) for anything custom","Reject free-form pseudo input from users of your generator","Test print CSS through swc in CI before shipping"],"tags":["css","swc","parser","at-rules","page-rule","print","syntax"],"backgroundTag":"css-page-rule-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"}