swc-project/swc · error · swc_css_parser::error::Error

Expected indent token

Error message

Expected indent token

What it means

An <extension-name> (used for names in @custom-media and @container-style extensions) must start as an identifier token. The parser found a non-Ident token (number, hash, delimiter, string) where the extension name was expected. The message text 'indent token' is a typo in the parser for 'ident token'.

Source

Thrown at crates/swc_css_parser/src/parser/at_rules/mod.rs:2535

                Ok(SizeFeatureValue::Function(function))
            }
            _ => Err(Error::new(
                span,
                ErrorKind::Expected("number, ident, dimension or function token"),
            )),
        }
    }
}

impl<I> Parse<ExtensionName> for Parser<I>
where
    I: ParserInput,
{
    fn parse(&mut self) -> PResult<ExtensionName> {
        let span = self.input.cur_span();

        if !is!(self, Ident) {
            return Err(Error::new(span, ErrorKind::Expected("indent token")));
        }

        // All extensions defined in this specification use a common syntax for defining
        // their ”names”: the <extension-name> production. An <extension-name> is any
        // identifier that starts with two dashes (U+002D HYPHEN-MINUS), like --foo, or
        // even exotic names like -- or ------. The CSS language will never use
        // identifiers of this form for any language-defined purpose, so it’s safe to
        // use them for author-defined purposes without ever having to worry about
        // colliding with CSS-defined names.
        match bump!(self) {
            Token::Ident { value, raw, .. } => {
                if !value.starts_with("--") {
                    return Err(Error::new(
                        span,
                        ErrorKind::Expected("Extension name should start with '--'"),
                    ));
                }

View on GitHub (pinned to 5176682b65)

Solutions

  1. Give the extension a valid identifier starting with '--': '@custom-media --wide (min-width: 100px);'
  2. Do not quote extension names
  3. If the name was omitted, add it before the media query
  4. Sanitize generated names so they match /--?[A-Za-z_][A-Za-z0-9_-]*/

Example fix

/* before */
@custom-media 123wide (min-width: 100px);
/* after */
@custom-media --wide (min-width: 100px);
Defensive patterns

Strategy: validation

Validate before calling

function isValidExtensionNameToken(src) {
  return /^--?[A-Za-z_-][\w-]*/.test(src); // starts as an identifier (ideally with '--')
}

Type guard

// Rust
fn is_extension_name_ident(s: &str) -> bool {
  let mut c = s.chars();
  matches!(c.next(), Some(a if a.is_ascii_alphabetic() || a == '_' || a == '-'))
}

Try / catch

// Rust
let name = if is_extension_name_ident(&raw) { raw } else { format!("--{raw}") }; // normalize, then parse

Prevention

When it happens

Trigger: '@custom-media 123wide (min-width: 100px);', '@custom-media "--wide" ...', or any extension-name slot whose first token is not an identifier.

Common situations: Naming custom media starting with a digit, quoting the name, or omitting the name so the next token (e.g. '(' of the media condition) is read as the name; generator code that interpolates an empty or numeric name.

Related errors


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