{"record":{"id":"175ae151b5fcb40b","repo":"swc-project/swc","slug":"percentage-function-math-functions-or-number-to","errorCode":null,"errorMessage":"percentage, function (math functions) or number token","messagePattern":"percentage, function \\(math functions\\) or number token","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"crates/swc_css_parser/src/parser/values_and_units/mod.rs","lineNumber":745,"sourceCode":"\n                if (is!(self, \",\") || has_variable) && is_legacy_syntax {\n                    if is!(self, \",\") {\n                        values.push(ComponentValue::Delimiter(self.parse()?));\n                    }\n\n                    self.input.skip_ws();\n\n                    let alpha_value = self.try_parse_variable_function(\n                        |parser, has_variable_before| match cur!(parser) {\n                            tok!(\"number\") | tok!(\"percentage\") => {\n                                Ok(Some(ComponentValue::AlphaValue(parser.parse()?)))\n                            }\n                            Token::Function { value, .. } if is_math_function(value) => {\n                                Ok(Some(ComponentValue::Function(parser.parse()?)))\n                            }\n                            _ => {\n                                if !has_variable_before {\n                                    Err(Error::new(\n                                        parser.input.cur_span(),\n                                        ErrorKind::Expected(\n                                            \"percentage, function (math functions) or number token\",\n                                        ),\n                                    ))\n                                } else {\n                                    Ok(None)\n                                }\n                            }\n                        },\n                        &mut has_variable,\n                    )?;\n\n                    if let Some(alpha_value) = alpha_value {\n                        values.push(alpha_value);\n                    }\n\n                    self.input.skip_ws();","sourceCodeStart":727,"sourceCodeEnd":763,"githubUrl":"https://github.com/swc-project/swc/blob/5176682b65416c6b5de6b47379ae1588ea3ecb3f/crates/swc_css_parser/src/parser/values_and_units/mod.rs#L727-L763","documentation":"Thrown by swc_css_parser while parsing the ALPHA channel of a LEGACY comma-syntax rgb()/rgba()/hsl()/hsla() (crates/swc_css_parser/src/parser/values_and_units/mod.rs:735-757). After the third comma, alpha accepts only number, percentage, or math function — there is no ident arm, so the keyword 'none' and every other word are rejected with ErrorKind::Expected(\"percentage, function (math functions) or number token\") at the current span. has_variable_before (a var()/env()/constant() earlier) still suppresses the error.","triggerScenarios":"parse_string on 'rgb(0, 0, 0, none)', 'rgba(0, 0, 0, transparent)', 'hsl(0, 0%, 0%, 50px)', 'rgb(0,0,0,)'. The '_' arm at line 743 fires because the token after the third comma matches none of tok!(\"number\")/tok!(\"percentage\")/math-function.","commonSituations":"Adding CSS Color 4 'none' alpha to old comma-syntax rules during incremental adoption; keywords like 'transparent' used as an alpha shortcut; units pasted into alpha; trailing empty slot after a dangling comma in generated CSS.","solutions":["Use a number or percentage for legacy alpha: 'rgb(0, 0, 0, 0.5)' or 'rgba(0, 0, 0, 50%)'.","'none' alpha requires modern syntax: 'rgb(0 0 0 / none)'.","Remove keywords/units from the alpha slot; 'transparent' is a standalone color value, not an alpha.","Wrap dynamic alpha in var(): 'rgb(0, 0, 0, var(--a))'."],"exampleFix":"/* before */\ncolor: rgb(0, 0, 0, none);\ncolor: rgba(0, 0, 0, transparent);\n\n/* after */\ncolor: rgb(0 0 0 / none);\ncolor: rgba(0, 0, 0, 0);\ncolor: transparent;","handlingStrategy":"try-catch","validationCode":"fn legacy_alpha_ok(arg: &str) -> bool {\n    let a = arg.trim();\n    a.parse::<f64>().is_ok()\n        || a.ends_with('%')\n        || a.starts_with(\"var(\")\n        || a.ends_with(')') && [\"calc(\",\"min(\",\"max(\",\"clamp(\"].iter().any(|f| a.to_ascii_lowercase().starts_with(f)))\n    // 'none', 'transparent', '50px', '' all fail: legacy alpha is number/percentage/math-fn only\n}","typeGuard":"fn is_legacy_alpha_candidate(text: &str) -> bool {\n    let t = text.trim();\n    t.parse::<f64>().is_ok() || t.ends_with('%') || t.starts_with(\"var(\")\n}","tryCatchPattern":"match swc_css_parser::parse_string::<Stylesheet>(css, config) {\n    Ok(sheet) => sheet,\n    Err(err) => {\n        if matches!(&err.kind(), ErrorKind::Expected(m) if m == \"percentage, function (math functions) or number token\") {\n            // legacy comma alpha got 'none'/keyword/unit; use a number/percentage or switch to '/ none' modern syntax\n        }\n        return Err(err.into());\n    }\n}","preventionTips":["Legacy comma syntax has NO 'none' alpha — switch to 'rgb(0 0 0 / none)' for that.","'transparent' is a color keyword, never an alpha value; use alpha 0.","Never leave an empty 4th slot after a trailing comma in generated rgba()."],"tags":["css","swc","css-parser","rgb","alpha","legacy-syntax","unexpected-token"],"backgroundTag":"css-color-alpha-value-invalid","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"}