{"record":{"id":"264d2c1066de3cd0","repo":"swc-project/swc","slug":"expected-hash-token","errorCode":null,"errorMessage":"Expected hash token","messagePattern":"Expected hash token","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"crates/swc_css_parser/src/parser/values_and_units/mod.rs","lineNumber":2428,"sourceCode":"                    ErrorKind::Expected(\n                        \"hash, ident (with named color or 'transparent' value) or function (with \\\n                         color function name) token\",\n                    ),\n                ));\n            }\n        }\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            _ => {","sourceCodeStart":2410,"sourceCodeEnd":2446,"githubUrl":"https://github.com/swc-project/swc/blob/5176682b65416c6b5de6b47379ae1588ea3ecb3f/crates/swc_css_parser/src/parser/values_and_units/mod.rs#L2410-L2446","documentation":"Thrown by the Parse<HexColor> impl in swc_css_parser when a hex color is expected but the current token is not a hash token. The impl checks is!(self, \"#\") first; an ident ('fff'), a number ('fff' after a failed escape), a string, or EOF fails immediately with this error. In normal flows AbsoluteColorBase only delegates here after seeing a '#', so hitting it usually means typed HexColor parsing was invoked on the wrong token or input position.","triggerScenarios":"Calling typed <hex-color> parsing on values like 'fff' (missing '#'), 'red', '', or when the parser cursor already consumed the '#' (double-parsing the same position).","commonSituations":"Code that strips '#' to normalize colors and forgets to re-add it before re-parsing, and utility functions assuming any color string is hex.","solutions":["Prefix the value with '#': 'fff' -> '#fff'.","Re-add '#' after any normalization that strips it (e.g. shorthand expansion).","Before typed hex parsing, check the string starts with '#'."],"exampleFix":"/* before */\na { color: fff; }\n\n/* after */\na { color: #fff; }","handlingStrategy":"type-guard","validationCode":"function startsWithHash(v: string): boolean {\n  return v.trim().startsWith('#');\n}","typeGuard":"fn is_hash_prefixed(v: &str) -> bool {\n    v.trim_start().starts_with('#')\n}","tryCatchPattern":"use swc_css_parser::error::ErrorKind;\nif let Err(e) = parse_input::<Stylesheet>(src, opts) {\n    if matches!(e.kind(), ErrorKind::Expected(\"hash token\")) {\n        return Err(format!(\"expected #hex color at {:?}\", e.span()).into());\n    }\n    return Err(e.into());\n}","preventionTips":["Re-add '#' after any normalization pipeline that strips it (shorthand expansion, comparison code).","Model colors as structured RGBA in code and serialize to hex only at the boundary.","Do not double-parse past a '#' the cursor already consumed."],"tags":["css","swc","parser","color","hex","hash-token"],"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-14T00:17:10.932Z"}