FyroxEngine/Fyrox · error
Failed to import animation
Error message
Failed to import animation: {} What it means
During glTF animation import, import_animation returned Err for one animation; the loader logs this error with the animation's name and simply skips it, so the resulting model has fewer animations than the source glTF. The actual reason is only in the inner error, which is discarded here.
Solutions
- Check the glTF in a validator (gltf-validator / gltf.report) to find the invalid animation channel/sampler
- Ensure animated nodes are part of the imported scene graph (skin hierarchy included in the node mapping)
- Re-export from the DCC tool with animation sampling enabled and only supported interpolation modes
- Log the inner import_animation error (modify code or check for related warnings) to identify the exact failing channel
Example fix
// before: animation silently missing
let model = resource_manager.request::<Model>("character.glb");
// after: confirm animations count matches source
let model = resource_manager.request::<Model>("character.glb");
if let ResourceState::Ok(m) = model.state() {
assert_eq!(m.animations_ref().len(), expected_animation_count, "glTF animation failed to import");
} Defensive patterns
Strategy: validation
Validate before calling
// After model load, verify animations count matches the source glTF let doc = gltf::Gltf::from_slice(&bytes)?; assert_eq!(doc.animations().len(), model_resource.animations_len(), "animation skipped during import");
Prevention
- Validate glTF files with gltf-validator in your asset pipeline
- Ensure animated nodes belong to the imported scene/skin hierarchy
- Re-export animations with sampling enabled and standard interpolation
- Count imported animations after load and compare with the source file
When it happens
Trigger: import_from_slice loading a glTF whose animation references nodes that couldn't be mapped to handles, samplers/channels with invalid accessors or unsupported interpolation, or empty/ corrupt buffers.
Common situations: glTF animations targeting nodes pruned during import, animations on skeleton bones not shared with the skin, exporters writing non-standard sampler data, or glb files with truncated buffer views.
Related errors
- glTF material failed to import. Reason
- : Model has triangles with repeated vertices
- : Mesh has a triangle with a zero-length edge!
- : Mesh has a triangle with edge length
- A node with existing name
AI-assisted analysis of FyroxEngine/Fyrox@76c91aad8e (2026-09-10).
Data as JSON: /api/errors/723dd446a43e2985.
Report an issue: GitHub.
Appendix: source
Thrown at fyrox-impl/src/resource/gltf/animation.rs:295
/// a handle can be looked up using the index of a node within the document. Animations in glTF specify their target
/// nodes by their index within the node list of the document, and these indices need to be translated into handles.
///
/// * `buffers`: A slice containing a list of byte-vectors, one for each buffer in the glTF document.
/// Animations in glTF make reference to data stored in the document's list of buffers by index.
/// This slcie allows an index into the document's list of buffers to be translated into actual bytes of data.
pub fn import_animations(
doc: &gltf::Document,
node_handles: &[Handle<Node>],
graph: &Graph,
buffers: &[Vec<u8>],
) -> Vec<Animation> {
let mut imports: Vec<ImportedAnimation> = Vec::with_capacity(doc.animations().len());
for animation in doc.animations() {
if let Ok(mut import) = import_animation(&animation, node_handles, buffers) {
import.simplify_curves();
imports.push(import);
} else {
Log::err(format!(
"Failed to import animation: {}",
animation.name().unwrap_or("[Unnamed]")
));
}
}
remove_fixed_targets(imports.as_mut_slice(), graph);
let mut result: Vec<Animation> = Vec::with_capacity(imports.len());
for import in imports {
result.push(import.into_animation());
}
result
}
fn import_animation(
animation: &gltf::Animation,
node_handles: &[Handle<Node>],
buffers: &[Vec<u8>],
) -> Result<ImportedAnimation> {View on GitHub (pinned to 76c91aad8e)