bevyengine/bevy · error · WorldInstanceSpawnError
world contains the unregistered component `{type_path}`. con
Error message
world contains the unregistered component `{type_path}`. consider adding `#[reflect(Component)]` to your type What it means
When bevy_world_serialization spawns a saved World into your app, it reflectively instantiates every component stored in the asset. Each component type must be registered in the app's type registry AND flagged as a component via #[reflect(Component)] (resources via #[reflect(Resource)]). If a stored component's type_path has no such registration, spawning returns WorldInstanceSpawnError::UnregisteredComponent with "world contains the unregistered component `{type_path}`. consider adding `#[reflect(Component)]` to your type".
Source
Thrown at crates/bevy_world_serialization/src/world_asset_spawner.rs:112
// apart and not reload the in setthose cases as it's unlikely to be an actual asset change.
debounced_world_asset_events: HashMap<AssetId<WorldAsset>, u32>,
dynamic_world_asset_event_reader: MessageCursor<AssetEvent<DynamicWorld>>,
// TODO: temp fix for https://github.com/bevyengine/bevy/issues/12756 effect on dynamic worlds
// See debounced_world_asset_events
debounced_dynamic_world_asset_events: HashMap<AssetId<DynamicWorld>, u32>,
world_assets_to_spawn: Vec<(Handle<WorldAsset>, InstanceId, Option<Entity>)>,
dynamic_worlds_to_spawn: Vec<(Handle<DynamicWorld>, InstanceId, Option<Entity>)>,
world_assets_to_despawn: Vec<AssetId<WorldAsset>>,
dynamic_worlds_to_despawn: Vec<AssetId<DynamicWorld>>,
instances_to_despawn: Vec<InstanceId>,
instances_ready: Vec<(InstanceId, Option<Entity>)>,
}
/// Errors that can occur when spawning a world asset.
#[derive(Error, Debug)]
pub enum WorldInstanceSpawnError {
/// `WorldAsset` contains an unregistered component type.
#[error("world contains the unregistered component `{type_path}`. consider adding `#[reflect(Component)]` to your type")]
UnregisteredComponent {
/// Type of the unregistered component.
type_path: String,
},
/// `WorldAsset` contains an unregistered resource type.
#[error("world contains the unregistered resource `{type_path}`. consider adding `#[reflect(Resource)]` to your type")]
UnregisteredResource {
/// Type of the unregistered resource.
type_path: String,
},
/// `WorldAsset` contains an unregistered type.
#[error(
"world contains the unregistered type `{std_type_name}`. \
consider reflecting it with `#[derive(Reflect)]` \
and registering the type using `app.register_type::<T>()`"
)]
UnregisteredType {
/// The [type name](std::any::type_name) for the unregistered type.View on GitHub (pinned to 396ca72708)
Solutions
- Add #[derive(Component, Reflect)] with #[reflect(Component)] to the listed type (and #[reflect(Resource)] for resources).
- Register the type at startup: app.register_type::<TheListedType>(); — the error message names the exact type_path to register.
- Make sure the plugin that owns/registers the component is actually added to the App before spawning the world.
- Keep a single register_all_types-style registration list shared by both the exporter and importer apps so serialized sets stay in sync.
Example fix
// before #[derive(Component, Reflect)] struct Health(u32); // no #[reflect(Component)], or never registered // after #[derive(Component, Reflect)] #[reflect(Component)] struct Health(u32); // and at startup: app.register_type::<Health>();
Defensive patterns
Strategy: try-catch
Validate before calling
// ensure every component type in a world save is registered before spawning
fn assert_registered<T: bevy::reflect::GetTypeRegistration>(app: &mut App) {
app.register_type::<T>();
} Try / catch
match world_spawner.spawn_sync(&mut world, &world_handle) {
Ok(instance) => { info!("spawned world instance {instance:?}"); }
Err(WorldInstanceSpawnError::UnregisteredComponent { type_path }) => {
error!("{type_path} is not registered — add #[reflect(Component)] and App::register_type::<{type_path}>()");
}
Err(e) => error!("world spawn failed: {e}"),
} Prevention
- Register every reflected component/resource in the plugin that defines it, so adding the plugin is sufficient.
- Share one registration list (or app.register_type_data audits) between exporter and importer apps.
- Treat the error's type_path as the exact todo list; fix and restart.
- Add an integration test that spawns each shipped .world asset to catch drift at CI time.
When it happens
Trigger: Spawning a .world asset serialized from an app that had component types your app has not registered; forgetting app.register_type::<T>() for a component included in the world; deriving Reflect without #[reflect(Component)]; missing the plugin that owns and registers the component.
Common situations: Sharing world saves between projects or across team members whose apps register different types; modular apps where the serialized world includes types from a plugin that the loading scene forgot to add; upgrading Bevy and moving components into new crates without updating registrations.
Related errors
- Error while trying to read the world file: {0}
- Could not parse RON: {0}
- component should represent a type.
- `{type_path}` should be registered in type registry via `App
- `{type_path}` should have #[reflect(Component)] or #[reflect
AI-assisted analysis of bevyengine/bevy@396ca72708 (2026-08-20).
Data as JSON: /api/errors/97efc34915d406fc.
Report an issue: GitHub.