DioxusLabs/dioxus · error

Failed to deserialize asset. Make sure you built with the ma

Error message

Failed to deserialize asset. Make sure you built with the matching version of the Dioxus CLI

What it means

asset!() metadata is serialized by the dx CLI into linker symbols at bundle time. BundledAsset::bundled() reads those raw bytes and runs deserialize_const!, which validates the serialized shape against the manganis-core version compiled into your app. When the CLI that bundled the assets and the library that reads them disagree on the serialization format, deserialization returns Err and this expect panics.

Source

Thrown at packages/manganis/manganis-core/src/asset.rs:152

        // Read the slice using volatile reads to prevent the compiler from optimizing
        // away the read at compile time
        let bundled = (self.bundled)();
        let ptr = bundled as *const [u8] as *const u8;
        let len = bundled.len();
        if ptr.is_null() {
            panic!(
                "Tried to use an asset that was not bundled. Make sure you are compiling dx as the linker"
            );
        }
        let mut bytes = Vec::with_capacity(len);
        for byte in 0..len {
            // SAFETY: We checked that the pointer was not null above. The pointer is valid for reads and
            // since we are reading a u8 there are no alignment requirements
            let byte = unsafe { std::ptr::read_volatile(ptr.add(byte)) };
            bytes.push(byte);
        }

        deserialize_const!(BundledAsset, bytes.as_slice()).expect("Failed to deserialize asset. Make sure you built with the matching version of the Dioxus CLI").1
    }

    /// Return a canonicalized path to the asset
    ///
    /// Attempts to resolve it against an `assets` folder in the current directory.
    /// If that doesn't exist, it will resolve against the cargo manifest dir
    pub fn resolve(&self) -> PathBuf {
        #[cfg(feature = "dioxus")]
        // If the asset is relative, we resolve the asset at the current directory
        if !dioxus_core_types::is_bundled_app() {
            return PathBuf::from(self.bundled().absolute_source_path.as_str());
        }

        #[cfg(feature = "dioxus")]
        let bundle_root = {
            let base_path = dioxus_cli_config::base_path();
            let base_path = base_path
                .as_deref()

View on GitHub (pinned to 393d190a80)

Solutions

  1. Update dx and the dioxus/manganis dependencies to the same release together
  2. cargo clean and rebuild so assets are re-bundled by the matching CLI
  3. Compare dx --version against the dioxus version in Cargo.lock and reconcile them
  4. If pinned to an old CLI, pin the matching dioxus crate versions in Cargo.toml
Defensive patterns

Strategy: validation

Validate before calling

#[test]
fn toolchain_versions_match() {
    let lock = std::fs::read_to_string("Cargo.lock").unwrap();
    assert!(lock.contains("name = \"dioxus\""));
    // compare against `dx --version` in CI to keep dx and crates in lockstep
}

Prevention

When it happens

Trigger: Calling .bundled()/.resolve() on an asset at runtime when the app was bundled by a dx CLI from a different release than the dioxus/manganis crates compiled into the binary; incremental builds that preserved old linker symbols across an upgrade.

Common situations: Upgrading dioxus crates but not dx (or vice versa); switching between stable and nightly dx builds; stale target/ directory after a version bump.

Related errors


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