{"record":{"id":"81b1e1d14a96581e","repo":"swc-project/swc","slug":"unexpected-character-in-hex-color","errorCode":null,"errorMessage":"Unexpected character in hex color","messagePattern":"Unexpected character in hex color","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"crates/swc_css_parser/src/parser/values_and_units/mod.rs","lineNumber":2434,"sourceCode":"        }\n    }\n}\n\nimpl<I> Parse<HexColor> for Parser<I>\nwhere\n    I: ParserInput,\n{\n    fn parse(&mut self) -> PResult<HexColor> {\n        let span = self.input.cur_span();\n\n        if !is!(self, \"#\") {\n            return Err(Error::new(span, ErrorKind::Expected(\"hash token\")));\n        }\n\n        match bump!(self) {\n            Token::Hash { value, raw, .. } => {\n                if value.chars().any(|x| !x.is_ascii_hexdigit()) {\n                    return Err(Error::new(\n                        span,\n                        ErrorKind::Unexpected(\"character in hex color\"),\n                    ));\n                }\n\n                Ok(HexColor {\n                    span,\n                    value,\n                    raw: Some(raw),\n                })\n            }\n            _ => {\n                unreachable!()\n            }\n        }\n    }\n}\n","sourceCodeStart":2416,"sourceCodeEnd":2452,"githubUrl":"https://github.com/swc-project/swc/blob/5176682b65416c6b5de6b47379ae1588ea3ecb3f/crates/swc_css_parser/src/parser/values_and_units/mod.rs#L2416-L2452","documentation":"Thrown by Parse<HexColor> in swc_css_parser when the token is a hash but its value contains characters outside [0-9a-fA-F]. After bumping Token::Hash it validates every char with is_ascii_hexdigit(); idents-as-hashes such as '#gg', '#ff00zz', or '#red' (r is not a hex digit) fail with the span of the whole hash token. Note the parser does not enforce 3/4/6/8 digit lengths here - only the character set.","triggerScenarios":"Values like 'color: #gg', 'color: #ff00zz', 'color: #0f0f0g', or CSS-module class selectors mistakenly parsed as colors ('#.side' style content in a color slot).","commonSituations":"Hash-prefixed identifiers mistaken for colors (e.g. '#main'), color strings with g-z characters from bad copy-paste, and hand-rolled color shorteners corrupting hex digits.","solutions":["Fix the hex digits: '#gg' -> '#ccc'-style valid hex; only 0-9 and a-f characters.","If the string is an id/anchor ('#main'), it is not a color; move it out of the color grammar.","Validate hex bodies with ^#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$ before parsing."],"exampleFix":"/* before */\na { color: #ff00zz; }\n\n/* after */\na { color: #ff00aa; }","handlingStrategy":"validation","validationCode":"const HEX = /^#(?:[0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/;\nfunction isValidHexColor(v: string): boolean {\n  return HEX.test(v.trim());\n}","typeGuard":"fn is_valid_hex_color(v: &str) -> bool {\n    let b = v.as_bytes();\n    matches!(b.len(), 4 | 5 | 7 | 9)\n        && b[0] == b'#'\n        && b[1..].iter().all(|c| c.is_ascii_hexdigit())\n}","tryCatchPattern":"use swc_css_parser::error::ErrorKind;\nif let Err(e) = parse_input::<Stylesheet>(src, opts) {\n    if matches!(e.kind(), ErrorKind::Unexpected(\"character in hex color\")) {\n        return Err(format!(\"bad hex digits at {:?}\", e.span()).into());\n    }\n    return Err(e.into());\n}","preventionTips":["Validate hex bodies (and ideally 3/4/6/8 lengths) with a regex before parsing.","Never feed '#id'-style anchors or CSS-module class names into color slots.","When mutating hex strings (darken/lighten), assert the charset stays [0-9a-f]."],"tags":["css","swc","parser","color","hex","validation"],"backgroundTag":"css-invalid-hex-color","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"}