swc-project/swc · error · Error

percentage, function (math functions) or number token

Error message

percentage, function (math functions) or number token

What it means

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.

Source

Thrown at crates/swc_css_parser/src/parser/values_and_units/mod.rs:745

                if (is!(self, ",") || has_variable) && is_legacy_syntax {
                    if is!(self, ",") {
                        values.push(ComponentValue::Delimiter(self.parse()?));
                    }

                    self.input.skip_ws();

                    let alpha_value = self.try_parse_variable_function(
                        |parser, has_variable_before| match cur!(parser) {
                            tok!("number") | tok!("percentage") => {
                                Ok(Some(ComponentValue::AlphaValue(parser.parse()?)))
                            }
                            Token::Function { value, .. } if is_math_function(value) => {
                                Ok(Some(ComponentValue::Function(parser.parse()?)))
                            }
                            _ => {
                                if !has_variable_before {
                                    Err(Error::new(
                                        parser.input.cur_span(),
                                        ErrorKind::Expected(
                                            "percentage, function (math functions) or number token",
                                        ),
                                    ))
                                } else {
                                    Ok(None)
                                }
                            }
                        },
                        &mut has_variable,
                    )?;

                    if let Some(alpha_value) = alpha_value {
                        values.push(alpha_value);
                    }

                    self.input.skip_ws();

View on GitHub (pinned to 5176682b65)

Solutions

  1. Use a number or percentage for legacy alpha: 'rgb(0, 0, 0, 0.5)' or 'rgba(0, 0, 0, 50%)'.
  2. 'none' alpha requires modern syntax: 'rgb(0 0 0 / none)'.
  3. Remove keywords/units from the alpha slot; 'transparent' is a standalone color value, not an alpha.
  4. Wrap dynamic alpha in var(): 'rgb(0, 0, 0, var(--a))'.

Example fix

/* before */
color: rgb(0, 0, 0, none);
color: rgba(0, 0, 0, transparent);

/* after */
color: rgb(0 0 0 / none);
color: rgba(0, 0, 0, 0);
color: transparent;
Defensive patterns

Strategy: try-catch

Validate before calling

fn legacy_alpha_ok(arg: &str) -> bool {
    let a = arg.trim();
    a.parse::<f64>().is_ok()
        || a.ends_with('%')
        || a.starts_with("var(")
        || a.ends_with(')') && ["calc(","min(","max(","clamp("].iter().any(|f| a.to_ascii_lowercase().starts_with(f)))
    // 'none', 'transparent', '50px', '' all fail: legacy alpha is number/percentage/math-fn only
}

Type guard

fn is_legacy_alpha_candidate(text: &str) -> bool {
    let t = text.trim();
    t.parse::<f64>().is_ok() || t.ends_with('%') || t.starts_with("var(")
}

Try / catch

match swc_css_parser::parse_string::<Stylesheet>(css, config) {
    Ok(sheet) => sheet,
    Err(err) => {
        if matches!(&err.kind(), ErrorKind::Expected(m) if m == "percentage, function (math functions) or number token") {
            // legacy comma alpha got 'none'/keyword/unit; use a number/percentage or switch to '/ none' modern syntax
        }
        return Err(err.into());
    }
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of swc-project/swc@5176682b65 (2026-08-17). Data as JSON: /api/errors/175ae151b5fcb40b. Report an issue: GitHub.