bevyengine/bevy · error
Field name should be a valid tuple index
Error message
Field name should be a valid tuple index
What it means
ImageSaver with the default FromExtension setting resolved an extension from the destination path, but bevy's ImageFormat::from_extension does not recognize it (crates/bevy_image/src/saver.rs:40-41). The unrecognized extension string is carried in the error. Saving stops because there is no format to encode with.
Source
Thrown at crates/bevy_animation/src/animation_curves.rs:259
}
}
impl<C: Typed, P, F: Fn(&mut C) -> &mut P + 'static> AnimatedField<C, P, F> {
/// Creates a new instance of [`AnimatedField`]. This operates under the assumption that
/// `C` is a reflect-able struct, and that `field_name` is a valid field on that struct.
///
/// # Panics
/// If the type of `C` is not a struct or if the `field_name` does not exist.
pub fn new_unchecked(field_name: &str, func: F) -> Self {
let field_index;
if let TypeInfo::Struct(struct_info) = C::type_info() {
field_index = struct_info
.index_of(field_name)
.expect("Field name should exist");
} else if let TypeInfo::TupleStruct(struct_info) = C::type_info() {
field_index = field_name
.parse()
.expect("Field name should be a valid tuple index");
if field_index >= struct_info.field_len() {
panic!("Field name should be a valid tuple index");
}
} else {
panic!("Only structs are supported in `AnimatedField::new_unchecked`")
}
Self {
func,
evaluator_id: Hashed::new((TypeId::of::<C>(), field_index)),
marker: PhantomData,
}
}
}
/// This trait collects the additional requirements on top of [`Curve<T>`] needed for a
/// curve to be used as an [`AnimationCurve`].
pub trait AnimationCompatibleCurve<T>: Curve<T> + Debug + Clone + Reflectable {}View on GitHub (pinned to 396ca72708)
Solutions
- Rename the destination to an extension bevy recognizes, such as .png (also .jpg/.jpeg/.gif/.tga/.tiff/.webp etc. for ImageFormat)
- Pass the format explicitly if the format is supported but its extension is unusual: ImageSaverSettings { format: SaveImageFormatSetting::Format(ImageFormat::Png) }
- Check ImageFormat::from_extension at build time for every path you generate
Example fix
// before
let path = AssetPath::from_path(Path::new("icon.bmp"));
// after
let path = AssetPath::from_path(Path::new("icon.png"));
// or keep the name but pin the format:
let settings = ImageSaverSettings {
format: SaveImageFormatSetting::Format(ImageFormat::Png),
}; Defensive patterns
Strategy: validation
Validate before calling
use bevy_image::ImageFormat;
fn supported_extension(ext: &str) -> bool {
ImageFormat::from_extension(ext.to_ascii_lowercase()).is_some()
} Type guard
fn is_saveable_extension(ext: &str) -> bool {
// only PNG is actually writable today
matches!(ext.to_ascii_lowercase().as_str(), "png")
} Try / catch
match result {
Err(SaveImageError::UnknownExtension(ext)) => warn!("unknown extension '{ext}', rename to .png"),
other => other?,
} Prevention
- Whitelist save extensions (.png) at the point where paths enter your app
- Lowercase extensions before checking (from_extension matches lowercase)
- Note that a recognized extension is necessary but only .png is sufficient for saving
When it happens
Trigger: Saving to a path whose extension is not in bevy's ImageFormat extension table, e.g. "icon.bmp", "art.svg", "tex.pic" — ImageFormat::from_extension(extension) returns None and UnknownExtension(extension) is returned.
Common situations: Using image formats that bevy can load but not name from extension, or non-image extensions (".tmp", ".dat", ".svg"); generating files with custom suffixes; case-mangled or compound suffixes like "tex.v2".
Related errors
- Field name should exist
- invalid image extension: {0}
- invalid image mime type: {0}
- failed to load an image: {0}
- Union types are not supported yet.
AI-assisted analysis of bevyengine/bevy@396ca72708 (2026-08-20).
Data as JSON: /api/errors/d057eb1050994196.
Report an issue: GitHub.