FyroxEngine/Fyrox · critical
Unable to add a resource of type
Error message
Unable to add a resource of type {needed_type_uuid} from resource UUID {}! The resource is loaded but its actual data has type {type_uuid}! What it means
ResourceManager::add_resource<T>(resource) registers a typed resource and verifies, after adding, that the untyped resource's data type UUID matches T. A mismatch means the caller wrapped the wrong data type in the typed handle, so it panics instead of storing a lying entry.
Solutions
- Ensure the Resource<T> was created from data whose type UUID equals T's (construct via T's loader/constructor).
- Print/inspect resource.untyped.type_uuid_non_blocking() before adding and use the matching typed call.
- Fix generic parameters at the call site so T corresponds to the actual payload type.
- Use the untyped add path (state.add_resource) if intentional mixed types must be stored.
Example fix
// before let res = Resource::<Texture>::new(ResourceData::from_model_data(data)); rm.add_resource(&res)?; // payload is ModelData, handle says Texture // after let res = Resource::<Model>::new(ResourceData::from_model_data(data)); rm.add_resource(&res)?;
Defensive patterns
Strategy: validation
Validate before calling
// before add_resource::<T>, confirm the payload type matches T
debug_assert_eq!(
resource.untyped.type_uuid_non_blocking(),
Some(<T as Reflect>::type_info().type_uuid)
); Prevention
- Construct Resource<T> only through T-specific constructors/loaders.
- Avoid wildcard generic aliases that let T drift at call sites.
- Unit-test add_resource calls with representative payloads.
- Use distinct types (Texture, Model, SoundBuffer) instead of generic T in app code where possible.
When it happens
Trigger: Calling resource_manager.add_resource::<T>(...) (e.g. add_texture-like wrappers) with a Resource<T> whose underlying untyped data type UUID differs from T — typically from constructing the handle with mismatched generic parameters or mixed-up resources.
Common situations: Programmatic resource construction where the generic parameter drifted during refactor; wrapping an untyped resource produced by another loader; copying add_resource calls across resource kinds.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Unable to get a resource of type
- Unable to get a resource of type
- Unable to get a resource of type
- Cast to failed!
- Height data type error
AI-assisted analysis of FyroxEngine/Fyrox@76c91aad8e (2026-09-10).
Data as JSON: /api/errors/b6c40dc25f43d59c.
Report an issue: GitHub.
Appendix: source
Thrown at fyrox-resource/src/manager.rs:700
}
}
}
/// Add the given resource to the resource manager, based on the resource's UUID,
/// without initiating the loading of the resource. The given resource is modified
/// to be a reference to the shared data of an existing resource with the same UUID.
pub fn add_resource<T>(&self, resource: &mut Resource<T>)
where
T: TypedResourceData,
{
let mut state = self.state();
state.add_resource(&mut resource.untyped);
if let Some(type_uuid) = resource.untyped.type_uuid_non_blocking() {
let needed_type_uuid = <T as Reflect>::type_info().type_uuid;
if type_uuid != needed_type_uuid {
panic!(
"Unable to add a resource of type {needed_type_uuid} from resource UUID {}! The resource is \
loaded but its actual data has type {type_uuid}!",
resource.resource_uuid(),
);
}
}
}
/// The same as [`Self::request`], but returns [`None`] if type UUID of `T` does not match the actual type UUID
/// of the resource.
///
/// ## Panic
///
/// This method does not panic.
pub fn try_request<T>(&self, path: impl AsRef<Path>) -> Option<Resource<T>>
where
T: TypedResourceData,
{View on GitHub (pinned to 76c91aad8e)