bevyengine/bevy · error · GltfError

Gltf file name invalid

Error message

Gltf file name invalid

What it means

At loader/mod.rs:279 the loader converts the asset path with Path::to_str(), which returns None when the path contains bytes invalid in UTF-8; that None is packed into GltfError::Gltf(gltf::Error::Io(InvalidInput, "Gltf file name invalid")). So despite the wrapper this is specifically a non-UTF-8 filename/directory problem, not a content problem. Most common on Windows (WTF-8 paths) and after unzipping archives created with legacy encodings.

Source

Thrown at crates/bevy_gltf/src/loader/mod.rs:279

        } else {
            gltf::Gltf::from_slice_without_validation(bytes)?
        };

        // clone extensions to start with a fresh processing state
        let mut extensions = loader.extensions.read().await.clone();

        // Extensions can have data on the "root" of the glTF data.
        // Let extensions process the root data for the extension ids
        // they've subscribed to.
        for extension in extensions.iter_mut() {
            extension.on_root(load_context, &gltf, settings);
        }

        let file_name = load_context
            .path()
            .path()
            .to_str()
            .ok_or(GltfError::Gltf(gltf::Error::Io(Error::new(
                std::io::ErrorKind::InvalidInput,
                "Gltf file name invalid",
            ))))?
            .to_string();
        let buffer_data = load_buffers(&gltf, load_context).await?;

        let linear_textures = get_linear_textures(&gltf.document);

        #[cfg(feature = "bevy_animation")]
        let paths = if settings.load_animations {
            let mut paths = HashMap::<usize, (usize, Vec<Name>)>::default();
            for scene in gltf.scenes() {
                for node in scene.nodes() {
                    let root_index = node.index();
                    collect_path(&node, &[], &mut paths, root_index, &mut HashSet::default());
                }
            }
            paths

View on GitHub (pinned to 396ca72708)

Solutions

  1. Rename the file and every parent folder to valid UTF-8/ASCII.
  2. Re-extract archives with a tool honoring the UTF-8 flag.
  3. Sanitize asset paths at import time in your tooling (lossy-convert then rename on disk).

Example fix

# (before) name contains invalid UTF-8 bytes
assets/models/bad$'\xff'$'\xf6'name.gltf
# (after)
mv assets/models/bad* assets/models/scene.gltf
Defensive patterns

Strategy: validation

Validate before calling

fn path_loadable(path: &std::path::Path) -> bool {
    path.to_str().is_some() // same check the loader performs at loader/mod.rs:279
}

Type guard

fn is_utf8_path(p: &std::path::Path) -> bool {
    p.to_str().is_some()
}

Try / catch

match err {
    GltfError::Gltf(gltf::Error::Io(ref io)) if io.to_string().contains("file name invalid") => {
        error!("asset path is not valid UTF-8; rename the file/folder");
    }
    other => return Err(other.into()),
}

Prevention

When it happens

Trigger: Loading a glTF whose filename or any parent directory contains non-UTF-8 bytes (e.g. Latin-1 accented characters from an old zip, or mis-decoded byte sequences); GltfLoader::load reaching the file_name step after root-extension processing.

Common situations: Unzipping purchased model packs whose names use legacy code pages; files created by scripts from unvalidated byte strings; cross-platform asset drops onto Windows.

Related errors


AI-assisted analysis of bevyengine/bevy@396ca72708 (2026-08-20). Data as JSON: /api/errors/f0150495a8fb5391. Report an issue: GitHub.