DioxusLabs/dioxus · error

Invalid css

Error message

Invalid css

What it means

After reading the css module file, the macro parses it with manganis-core's lightweight class parser (get_class_mappings). Malformed CSS — unbalanced braces, broken selectors, nested :global() — yields a ParseError which the macro unwraps with expect("Invalid css"). The generic message discards the underlying parse error details, so you must lint the file to locate the fault.

Source

Thrown at packages/manganis/manganis-macro/src/css_module.rs:90

        const ASSET: manganis::Asset =
    };
    attribute.asset_parser.to_tokens(&mut linker_tokens);

    let asset = match attribute.asset_parser.asset.as_ref() {
        Ok(path) => path,
        Err(err) => {
            let err = err.to_string();
            tokens.append_all(quote! { compile_error!(#err) });
            return;
        }
    };

    let css = std::fs::read_to_string(asset).expect("Unable to read css module file");

    let mut values = Vec::new();

    let hash = create_module_hash(asset);
    let class_mappings = get_class_mappings(css.as_str(), hash.as_str()).expect("Invalid css");

    // Generate class struct field tokens.
    for (old_class, new_class) in class_mappings.iter() {
        let as_snake = to_snake_case(old_class);

        let ident = Ident::new(&as_snake, Span::call_site());
        values.push(quote! {
            pub const #ident: #struct_name_private::__CssIdent = #struct_name_private::__CssIdent { inner: #new_class };
        });
    }

    // We use a PhantomData to prevent Rust from complaining about an unused lifetime if a css module without any idents is used.
    tokens.extend(quote! {
        #[doc(hidden)]
        #[allow(missing_docs, non_snake_case)]
        mod #struct_name_private {
            use dioxus::prelude::*;

View on GitHub (pinned to 393d190a80)

Solutions

  1. Run the file through a CSS formatter/linter (prettier, stylelint) to pinpoint the syntax error
  2. Balance braces and write standard flat CSS selectors and classes
  3. Use a single level of :global(.class); never nest :global() inside :global()
  4. Remove preprocessor-only syntax (SCSS variables, nesting, mixins) from css module files

Example fix

// before (module.css)
.container { color: red;
// missing closing brace
// after
.container { color: red; }
Defensive patterns

Strategy: validation

Validate before calling

// build.rs or CI: lint css module files before compiling
fn css_parses(path: &std::path::Path) -> bool {
    let css = std::fs::read_to_string(path).unwrap();
    css.matches('{').count() == css.matches('}').count()
}
assert!(css_parses(std::path::Path::new("css/module.css")));

Prevention

When it happens

Trigger: A css module file containing syntax errors: unclosed { }, stray characters, invalid selector fragments, :global() nested inside :global(), or CSS constructs the class parser does not support.

Common situations: Hand-editing css module files and leaving an unbalanced brace; pasting preprocessor syntax (SCSS variables, nesting) into a plain css module; file truncated by tooling or a bad merge.

Related errors


AI-assisted analysis of DioxusLabs/dioxus@393d190a80 (2026-08-16). Data as JSON: /api/errors/1ac21be0f931421b. Report an issue: GitHub.