bevyengine/bevy · error · GltfError

failed to read bytes from an asset path: {0}

Error message

failed to read bytes from an asset path: {0}

What it means

GltfError::ReadAssetBytesError (#[from] ReadAssetBytesError) comes from load_context.read_asset_bytes(buffer_path) at loader/mod.rs:1948: the external .bin (or other embedded byte asset) resolved fine but could not be read from the asset source — missing file, permission failure, or an AssetSource that cannot serve that embedded path.

Source

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

    Base64Decode(#[from] base64::DecodeError),
    /// Unsupported buffer format.
    #[error("unsupported buffer format")]
    BufferFormatUnsupported,
    /// The buffer URI was unable to be resolved with respect to the asset path.
    #[error("invalid buffer uri: {0}. asset path error={1}")]
    InvalidBufferUri(String, ParseAssetPathError),
    /// Invalid image mime type.
    #[error("invalid image mime type: {0}")]
    #[from(ignore)]
    InvalidImageMimeType(String),
    /// Error when loading a texture. Might be due to a disabled image file format feature.
    #[error("You may need to add the feature for the file format: {0}")]
    ImageError(#[from] TextureError),
    /// The image URI was unable to be resolved with respect to the asset path.
    #[error("invalid image uri: {0}. asset path error={1}")]
    InvalidImageUri(String, ParseAssetPathError),
    /// Failed to read bytes from an asset path.
    #[error("failed to read bytes from an asset path: {0}")]
    ReadAssetBytesError(#[from] ReadAssetBytesError),
    /// Failed to load asset from an asset path.
    #[error("failed to load asset from an asset path: {0}")]
    AssetLoadError(#[from] AssetLoadError),
    /// Missing sampler for an animation.
    #[error("Missing sampler for animation {0}")]
    #[from(ignore)]
    MissingAnimationSampler(usize),
    /// Failed to generate tangents.
    #[error("failed to generate tangents: {0}")]
    GenerateTangentsError(#[from] bevy_mesh::GenerateTangentsError),
    /// Failed to generate morph targets.
    #[error("failed to generate morph targets: {0}")]
    MorphTarget(#[from] bevy_mesh::morph::MorphBuildError),
    /// Circular children in Nodes
    #[error("GLTF model must be a tree, found cycle instead at node indices: {0:?}")]
    #[from(ignore)]
    CircularChildren(String),

View on GitHub (pinned to 396ca72708)

Solutions

  1. Ship the whole export folder: .gltf plus .bin and textures as siblings.
  2. Check exact filename casing against the uri in the JSON.
  3. Verify the file is inside a registered asset folder and readable by the app.
  4. Switch to single-file GLB to remove external dependencies.
Defensive patterns

Strategy: validation

Validate before calling

fn external_bins_exist(model: &std::path::Path, json: &serde_json::Value) -> bool {
    let dir = model.parent().unwrap();
    json["buffers"].as_array().unwrap_or(&vec![]).iter()
        .filter_map(|b| b["uri"].as_str())
        .filter(|u| !u.starts_with("data:"))
        .all(|u| dir.join(u).exists())
}

Try / catch

match err {
    GltfError::ReadAssetBytesError(e) => {
        error!("could not read companion file: {e}; check casing and folder contents");
    }
    other => return Err(other.into()),
}

Prevention

When it happens

Trigger: Buffer uri says "scene.bin" but only model.gltf was copied into assets/; case-sensitivity mismatch (Scene.bin vs scene.bin on Linux); file locked or unreadable; a custom AssetSource/processor configuration that does not expose companion files.

Common situations: Copying models out of their export folder, zip extractions that flatten directories, deploying to case-sensitive servers, missing files in CI bundles.

Related errors


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