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

  1. Ensure the Resource<T> was created from data whose type UUID equals T's (construct via T's loader/constructor).
  2. Print/inspect resource.untyped.type_uuid_non_blocking() before adding and use the matching typed call.
  3. Fix generic parameters at the call site so T corresponds to the actual payload type.
  4. 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

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


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)