swc-project/swc · error · Error

Expected number or dimension token

Error message

Expected number or dimension token

What it means

Thrown by Parse<Hue> in swc_css_parser when a <hue> is expected but the current token is neither a number nor a dimension. Hue accepts a bare number ('hsl(120 50% 50%)') or an angle dimension that is then delegated to Parse<Angle> ('hsl(120deg 50% 50%)'); an ident ('red'), percentage, function, or EOF fails is_one_of!(self, "number", "dimension") with this error.

Source

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

        match cur!(self) {
            tok!("percentage") => Ok(AlphaValue::Percentage(self.parse()?)),
            tok!("number") => Ok(AlphaValue::Number(self.parse()?)),
            _ => {
                unreachable!()
            }
        }
    }
}

impl<I> Parse<Hue> for Parser<I>
where
    I: ParserInput,
{
    fn parse(&mut self) -> PResult<Hue> {
        if !is_one_of!(self, "number", "dimension") {
            let span = self.input.cur_span();

            return Err(Error::new(
                span,
                ErrorKind::Expected("number or dimension token"),
            ));
        }

        match cur!(self) {
            tok!("number") => Ok(Hue::Number(self.parse()?)),
            tok!("dimension") => Ok(Hue::Angle(self.parse()?)),
            _ => {
                unreachable!()
            }
        }
    }
}

impl<I> Parse<CmykComponent> for Parser<I>
where
    I: ParserInput,

View on GitHub (pinned to 5176682b65)

Solutions

  1. Put a number or angle in the hue slot: 'hsl(120 50% 50%)' or 'hsl(120deg 50% 50%)'.
  2. If the source is a named color, convert it to its hue/percent triplets or use the color directly as 'hsl(0 100% 50%)'-equivalent value.
  3. Validate hue strings with ^-?(\d+\.?\d*|\.\d+)(deg|grad|rad|turn)?$ before parsing.

Example fix

/* before */
a { color: hsl(red, 50%, 50%); }

/* after */
a { color: hsl(0 100% 50%); }
Defensive patterns

Strategy: validation

Validate before calling

const HUE = /^-?(\d+\.?\d*|\.\d+)(deg|grad|rad|turn)?$/i;
function isValidHue(v: string): boolean {
  return HUE.test(v.trim());
}

Type guard

fn is_hue_literal(v: &str) -> bool {
    match v.find(|c: char| c.is_ascii_alphabetic()) {
        Some(i) => v[..i].parse::<f64>().is_ok()
            && matches!(v[i..].to_ascii_lowercase().as_str(), "deg" | "grad" | "rad" | "turn"),
        None => v.parse::<f64>().is_ok(),
    }
}

Try / catch

use swc_css_parser::error::ErrorKind;
if let Err(e) = parse_input::<Stylesheet>(src, opts) {
    if matches!(e.kind(), ErrorKind::Expected("number or dimension token")) {
        return Err(format!("bad hue at {:?}", e.span()).into());
    }
    return Err(e.into());
}

Prevention

When it happens

Trigger: 'hsl(red, 50%, 50%)' (legacy code using a color keyword in the hue slot), 'hsl(50% 50% 50%)' (percentage hue), or 'hsl(... ' truncated at EOF before the hue token.

Common situations: Converting legacy comma-syntax hsl() where the first argument was sometimes a named color, and templates inserting a percentage where degrees are required.

Related errors


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