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

Expected ident, '*' or '|' delim tokens

Error message

Expected ident, '*' or '|' delim tokens

What it means

A type selector is a namespace prefix (optional) followed by either an element name (ident) or the universal selector '*'. After an optional prefix was handled, the current token is neither an ident nor '*', so there is no type selector to build. This includes the case where a namespace prefix ('ns|') was consumed but no name or '*' follows it.

Source

Thrown at crates/swc_css_parser/src/parser/selectors/mod.rs:516

                return Ok(TypeSelector::TagName(TagNameSelector {
                    span: span!(self, span.lo),
                    name: WqName {
                        span: span!(self, span.lo),
                        prefix,
                        value,
                    },
                }));
            }
            tok!("*") => {
                bump!(self);

                return Ok(TypeSelector::Universal(UniversalSelector {
                    span: span!(self, span.lo),
                    prefix,
                }));
            }
            _ => {
                return Err(Error::new(
                    span,
                    ErrorKind::Expected("ident, '*' or '|' delim tokens"),
                ));
            }
        }
    }
}

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

        let mut namespace = None;

        match cur!(self) {

View on GitHub (pinned to 5176682b65)

Solutions

  1. Complete the selector: 'ns|div {}' or 'ns|* {}'
  2. Drop the namespace prefix if you do not need it: 'div {}'
  3. Check for a stray '|' from a mis-escaped character ('a\|b' vs 'a|b')
  4. Lint selectors for a dangling '|' followed by non-name tokens

Example fix

/* before */
ns| { color: red; }
/* after */
ns|* { color: red; }
Defensive patterns

Strategy: validation

Validate before calling

// A '|' must be followed by an ident or '*'
function noDanglingNamespaceBar(sel) { return !/\|(?!\s*[\w*-])/.test(sel); }

Type guard

// Rust
fn type_selector_tail_ok(rest: &str) -> bool {
  let t = rest.trim_start();
  t == "*" || t.chars().next().map_or(false, |c| c.is_ascii_alphabetic() || c == '_' || c == '-')
}

Try / catch

// JS
try { parseSelector(sel, opts); } catch (e) { if (/ident, '\*' or '\|'/.test(e.message)) reportDanglingNamespace(sel); else throw e; }

Prevention

When it happens

Trigger: 'ns| { }' or 'ns|.a { }' (prefix with no tag/universal after the bar), a bare '|' followed by junk, or any type-selector position where the token is a delimiter, string, or EOF-adjacent token.

Common situations: Namespace-prefixed selectors (SVG/MathML, XML pipelines) where the element after '|' was typo'd or stripped by minification; templating that interpolates an empty tag name; copy-paste of namespace examples into plain HTML CSS where the prefix is then dangling.

Related errors


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