swc-project/swc · error · Error
number, dimension, function (math functions) or ident (with
Error message
number, dimension, function (math functions) or ident (with 'none' value) token
What it means
Thrown by swc_css_parser when the FIRST channel of an hsl()/hsla() function (the hue) begins with a token that is not a number, dimension, ident, or math function (crates/swc_css_parser/src/parser/values_and_units/mod.rs:473-485). The parser emits ErrorKind::Expected("number, dimension, function (math functions) or ident (with 'none' value) token") at the current span. It only fires when has_variable_before is false — once a var()/env()/constant() appeared, the arm yields Ok(None) and the parser stays lenient.
Source
Thrown at crates/swc_css_parser/src/parser/values_and_units/mod.rs:475
}
tok!("ident") => {
let ident: Box<Ident> = parser.parse()?;
if ident.value.eq_ignore_ascii_case("none") {
Ok(Some(ComponentValue::Ident(ident)))
} else {
Err(Error::new(
ident.span,
ErrorKind::Expected("'none' value of an ident token"),
))
}
}
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(
"number, dimension, function (math functions) or \
ident (with 'none' value) token",
),
))
} else {
Ok(None)
}
}
},
&mut has_variable,
)?;
if let Some(hue_or_none) = hue_or_none {
values.push(hue_or_none);
}
View on GitHub (pinned to 5176682b65)
Solutions
- Write the hue as number or dimension: 'hsl(240 100% 50%)' or 'hsl(240deg 100% 50%)'.
- Remove quotes around interpolated values before emitting CSS ('hsl(' + h + ' 100% 50%)').
- Keep hex colors as-is ('#fff') instead of forcing them into hsl().
- Use the error span from err.into_inner().0 to locate the bad token quickly.
Example fix
/* before */
color: hsl("240" 100% 50%);
color: hsl(#fff, 100%, 50%);
/* after */
color: hsl(240 100% 50%);
color: hsl(240deg 100% 50%); Defensive patterns
Strategy: try-catch
Validate before calling
fn hsl_hue_token_ok(raw: &str) -> bool {
let a = raw.trim();
match a.chars().next() {
Some(c) if c.is_ascii_digit() || c == '.' || c == '-' || c == '+' => true,
Some(_) => a.eq_ignore_ascii_case("none") || a.starts_with("var(") || a.ends_with(')'),
None => false, // empty hue slot will hit the fallback arm
}
} Type guard
fn is_hue_start_token(text: &str) -> bool {
let t = text.trim_start();
!t.is_empty()
&& !t.starts_with('#')
&& !t.starts_with('"')
&& !t.starts_with(',')
&& !t.starts_with('/')
} 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.contains("number, dimension, function (math functions) or ident")) => {
// hsl hue starts with an unexpected token (hash/string/comma); report span, skip declaration
Err(err.into())
}
Err(err) => Err(err.into()),
} Prevention
- Never quote interpolated hue values in generated CSS.
- Do not paste hex values into hsl(); branch to the hex form instead.
- Fail fast in codegen: assert the first non-space character of every hsl() argument is a digit, '.', '-', or a letter that starts var(/calc(.
When it happens
Trigger: parse_string on 'hsl(#fff, 100%, 50%)', 'hsl("240" 100% 50%)', 'hsl(, 100%, 50%)', or 'hsl(/ 100% 50%)' — the hue slot starts with a hash/string/comma/slash token and hits the '_' arm at line 473.
Common situations: Pasting a hex hue into hsl(); quoted hue values produced by JS template strings ('hsl("${h}", ...)'); malformed output from CSS-in-JS or older preprocessor loops; truncated files after minification or merge conflicts leaving an empty first argument.
Related errors
- percentage, function (math functions) or ident (with 'none'
- percentage, number, function (math functions) or ident (with
- comma token
- percentage, function (math functions) or number token
- internal error: entered unreachable code
AI-assisted analysis of swc-project/swc@5176682b65 (2026-08-17).
Data as JSON: /api/errors/5bab1edf4826612f.
Report an issue: GitHub.