DioxusLabs/dioxus · error

Unable to read css module file

Error message

Unable to read css module file

What it means

The css_module proc macro (behind the style! macro) resolves the referenced .css file and reads it with std::fs::read_to_string at compile time. Any IO failure — the file not existing at the resolved path, permission denied, or non-UTF-8 content — hits this expect and fails the compilation of the crate using the macro.

Source

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

    // Use the regular asset parser to generate the linker bridge.
    let mut linker_tokens = quote! {
        /// Auto-generated Manganis asset for css modules.
        #[allow(missing_docs)]
        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! {

View on GitHub (pinned to 393d190a80)

Solutions

  1. Verify the path relative to your crate root and create/restore the file
  2. Use an explicit relative path: style! { css: "./css/module.css" }
  3. Re-save the file with UTF-8 encoding if it came from another tool
  4. Fix permissions or CI checkout; restart rust-analyzer / cargo clean after path fixes
Defensive patterns

Strategy: validation

Validate before calling

fn css_module_readable(rel: &str) -> bool {
    let path = std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join(rel);
    path.exists() && std::fs::read_to_string(&path).is_ok()
}
assert!(css_module_readable("css/module.css")); // in build.rs or a test

Prevention

When it happens

Trigger: style! { css: "missing.css" } where the resolved path (relative to the crate manifest) doesn't exist, was renamed/deleted, has restrictive permissions, or contains non-UTF-8 bytes.

Common situations: Renaming/moving css files without updating the macro path; rust-analyzer resolving the asset root differently; case-sensitivity differences after moving a repo from macOS/Windows to Linux; CI checkout missing the file.

Related errors


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