bevyengine/bevy · error · BrpError

-23402

-23402

Error message

Unknown component type: `{}`

What it means

BRP's `world.mutate_component` handler looks the component name up with `type_registry.get_with_type_path(&component)`. If no registered type matches the string (neither full path nor registered short alias), it returns this COMPONENT_ERROR (-23402). The lookup happens before any entity or field access, so the request never reaches the entity.

Source

Thrown at crates/bevy_remote/src/builtin_methods.rs:1185

/// component.
pub fn process_remote_mutate_components_request(
    In(params): In<Option<Value>>,
    world: &mut World,
) -> BrpResult {
    let BrpMutateComponentsParams {
        entity,
        component,
        path,
        value,
    } = parse_some(params)?;
    let app_type_registry = world.resource::<AppTypeRegistry>().clone();
    let type_registry = app_type_registry.read();

    // Get the fully-qualified type names of the component to be mutated.
    let component_type: &TypeRegistration = type_registry
        .get_with_type_path(&component)
        .ok_or_else(|| {
            BrpError::component_error(anyhow!("Unknown component type: `{}`", component))
        })?;

    // Get the reflected representation of the component.
    let mut reflected = component_type
        .data::<ReflectComponent>()
        .ok_or_else(|| {
            BrpError::component_error(anyhow!("Component `{}` isn't registered", component))
        })?
        .reflect_mut(world.entity_mut(entity))
        .ok_or_else(|| {
            BrpError::component_error(anyhow!("Cannot reflect component `{}`", component))
        })?;

    // Get the type of the field in the component that is to be
    // mutated.
    let value_type: &TypeRegistration = type_registry
        .get_with_type_path(
            reflected

View on GitHub (pinned to 78002f65fa)

Solutions

  1. Use the exact fully-qualified type path (copy it from a `world.get_component` response or from `std::any::type_name` on the app side)
  2. Ensure the component derives `Reflect` and is registered: `#[derive(Component, Reflect)]` plus `app.register_type::<T>()`
  3. If the type lives in another crate, enable/verify that crate registers its types (most Bevy plugins do this in `Plugin::build`)

Example fix

// before (client payload)
{ "entity": 12, "component": "transform", "path": "translation", "value": [0.0, 1.0, 0.0] }

// after
{ "entity": 12,
  "component": "bevy_transform::components::transform::Transform",
  "path": "translation",
  "value": [0.0, 1.0, 0.0] }

// app side, if still unknown:
#[derive(Component, Reflect, Default)]
#[reflect(Component)]
struct Health(f32);
app.register_type::<Health>();
Defensive patterns

Strategy: validation

Validate before calling

// App side (Rust): assert the type path resolves before the client uses it
let registry = app.world().resource::<AppTypeRegistry>().read();
assert!(registry.get_with_type_path("my_game::Health").is_some(),
    "BRP clients expect my_game::Health to be registered");

Try / catch

if (res.error?.code === -23402 && /Unknown component type/i.test(res.error.message)) {
  const hint = await resolveTypePath(res.error.data); // e.g. ask user / fallback list
  retryWithFullyQualifiedName(hint);
}

Prevention

When it happens

Trigger: A `world.mutate_component` request whose `component` string is not a registered type path: a typo, a short name that isn't registered, or a component type that was never registered for reflection.

Common situations: Sending `"Transform"` vs `"bevy_transform::components::transform::Transform"` and the short alias isn't registered; the component comes from a plugin/crate that doesn't call `app.register_type::<T>()`; a BRP client written against a different Bevy version where type paths moved.

Related errors


AI-assisted analysis of bevyengine/bevy@78002f65fa (2026-08-16). Data as JSON: /api/errors/baae6ce218e14200. Report an issue: GitHub.