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

  1. Add #[derive(Component, Reflect)] with #[reflect(Component)] to the listed type (and #[reflect(Resource)] for resources).
  2. Register the type at startup: app.register_type::<TheListedType>(); — the error message names the exact type_path to register.
  3. Make sure the plugin that owns/registers the component is actually added to the App before spawning the world.
  4. 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

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


AI-assisted analysis of bevyengine/bevy@396ca72708 (2026-08-20). Data as JSON: /api/errors/97efc34915d406fc. Report an issue: GitHub.