swc-project/swc · error · Error
'none' value of an ident token
Error message
'none' value of an ident token
What it means
Thrown by swc_css_parser while parsing the FIRST channel of an rgb()/rgba() function (crates/swc_css_parser/src/parser/values_and_units/mod.rs:415-428). When that channel is an identifier, CSS Color 4 allows only the keyword 'none' (matched with eq_ignore_ascii_case); any other word is a grammar violation and the parser returns ErrorKind::Expected("'none' value of an ident token") with the span of the offending ident. Note this ident arm is unconditional, so it fires even in comma-style legacy syntax like rgb(red, 0, 0). The error only fires on literal tokens: if a var()/env()/constant() was consumed earlier, try_parse_variable_function returns Ok(None) instead of erroring.
Source
Thrown at crates/swc_css_parser/src/parser/values_and_units/mod.rs:423
"rgb" | "rgba" => {
let percentage_or_number_or_none = self.try_parse_variable_function(
|parser, has_variable_before| match cur!(parser) {
tok!("percentage") => {
Ok(Some(ComponentValue::Percentage(parser.parse()?)))
}
tok!("number") => Ok(Some(ComponentValue::Number(parser.parse()?))),
Token::Function { value, .. } if is_math_function(value) => {
Ok(Some(ComponentValue::Function(parser.parse()?)))
}
tok!("ident") => {
is_legacy_syntax = false;
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"),
))
}
}
_ => {
if !has_variable_before {
Err(Error::new(
parser.input.cur_span(),
ErrorKind::Expected(
"percentage, number, function (math functions) or \
ident (with 'none' value) token",
),
))
} else {
Ok(None)
}
}View on GitHub (pinned to 5176682b65)
Solutions
- Replace the ident channel with a numeric channel: 'color: rgb(red 0 0)' -> 'color: rgb(255 0 0)', or just write 'color: red' since the keyword is already a valid color.
- If you want keyword-derived channels, use relative color syntax: 'rgb(from red r g b)'.
- For dynamic values pass them through var(): 'rgb(var(--ch) 0 0)' — the parser skips the strict grammar once a var() is seen.
- Read err.kind()/err.message() and the span from err.into_inner().0 to pinpoint the exact ident in the source file.
Example fix
/* before */ color: rgb(red 0 0); color: rgb(red, 0, 0); /* after */ color: red; color: rgb(255 0 0); color: rgb(from red r g b);
Defensive patterns
Strategy: try-catch
Validate before calling
fn rgb_first_channel_ok(arg: &str) -> bool {
let a = arg.trim();
a.eq_ignore_ascii_case("none")
|| a.ends_with('%')
|| a.parse::<f64>().is_ok()
|| a.starts_with("var(")
|| a.starts_with("env(")
|| ["calc","min","max","clamp"].iter().any(|f| a.starts_with(f))
}
// before emitting generated CSS:
assert!(rgb_first_channel_ok(ch), "rgb() first channel must be number/percentage/none, got {ch}"); Type guard
fn is_valid_none_ident(ident: &swc_css_ast::Ident) -> bool {
ident.value.eq_ignore_ascii_case("none")
} Try / catch
let parsed = swc_css_parser::parse_string::<swc_css_ast::Stylesheet>(css, config);
if let Err(err) = parsed {
if matches!(&err.kind(), swc_css_parser::error::ErrorKind::Expected(m) if m.contains("'none' value of an ident token")) {
let (span, _) = err.into_inner();
// report: rgb()/rgba() channel is a keyword; only 'none' is allowed, span points at it
}
return Err(err.into());
} Prevention
- Never put named colors inside rgb()/rgba() channels; use them directly as the property value.
- Validate generated color channels with a small checker (number, percentage, 'none', var(), math function) before string-building CSS.
- Log err.message() plus the span from err.into_inner().0 so users of your tool see the exact offending word.
When it happens
Trigger: Calling swc_css_parser::parse_string (directly or via an swc-based minifier/transform) on CSS whose first rgb()/rgba() argument is a word that is not 'none': 'color: rgb(red 0 0)', 'rgb(red, 0, 0)', 'rgba(primary 25 50)'. The tok!("ident") arm at line 415 sets is_legacy_syntax = false, parses the ident, and errors at ident.span when the value check at line 420 fails.
Common situations: Using a named color inside rgb() instead of as the color value itself; template interpolation that inserts a variable name ('primary') instead of a number into a generated rgb() string; porting Sass/older tooling that tolerated keyword channels; hand-written design-token CSS pasted from specs that use lab/oklch-style keyword examples.
Related errors
- percentage, number, function (math functions) or ident (with
- comma token
- percentage, function (math functions) or number token
- number, dimension, function (math functions) or ident (with
- percentage, function (math functions) or ident (with 'none'
AI-assisted analysis of swc-project/swc@5176682b65 (2026-08-17).
Data as JSON: /api/errors/7abea286da01d2af.
Report an issue: GitHub.