bevyengine/bevy · error · BrpError

-23501

-23501

Error message

Resource is not registered: `{}`

What it means

BRP's `world.insert_resource` handler resolves the type path in the AppTypeRegistry (deserialization already succeeded), then asks `world.components().get_id(type_id)` for the resource's component id. In Bevy, a type only gets a component id once the world has initialized it (typically `app.init_resource::<T>()`); if that never happened, `get_id` returns None and this RESOURCE_ERROR (-23501) is returned.

Source

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

) -> BrpResult {
    let BrpInsertResourcesParams {
        resource: resource_path,
        value,
    } = parse_some(params)?;

    let app_type_registry = world.resource::<AppTypeRegistry>().clone();
    let type_registry = app_type_registry.read();

    let reflected_resource = deserialize_resource(&type_registry, &resource_path, value)
        .map_err(BrpError::resource_error)?;

    let resource_registration = get_resource_type_registration(&type_registry, &resource_path)
        .map_err(BrpError::resource_error)?;
    let type_id = resource_registration.type_id();
    let resource_id = world
        .components()
        .get_id(type_id)
        .ok_or(anyhow!("Resource is not registered: `{}`", resource_path))
        .map_err(BrpError::resource_error)?;
    world.insert_reflect_resource(resource_id, reflected_resource);

    Ok(Value::Null)
}

/// Handles a `world.mutate_components` request coming from a client.
///
/// This method allows you to mutate a single field inside an Entity's
/// component.
pub fn process_remote_mutate_components_request(
    In(params): In<Option<Value>>,
    world: &mut World,
) -> BrpResult {
    let BrpMutateComponentsParams {
        entity,
        component,
        path,

View on GitHub (pinned to 78002f65fa)

Solutions

  1. On the app side, call `app.init_resource::<MyResource>()` for the type before remote clients insert it
  2. Verify you actually need insertion: if the resource exists, use `world.mutate_resource` instead
  3. Re-send with the exact fully-qualified type path after confirming the resource is initialized (a `world.get_resource` probe returning data proves it)

Example fix

// before: app never initializes the resource
App::new().add_plugins(DefaultPlugins); // BRP insert_resource -> -23501

// after: declare the resource so the World registers its component id
App::new()
    .add_plugins(DefaultPlugins)
    .init_resource::<MyResource>(); // now remote insert/mutate works
Defensive patterns

Strategy: validation

Validate before calling

// Client: prove the resource is initialized before inserting
const probe = await brpCall("world.get_resource", { resource: path });
if (probe.error && probe.error.code === -23502 /* RESOURCE_NOT_PRESENT */) {
  await ensureAppInitializes(path); // app must init_resource::<T>() first
}

Try / catch

if (res.error?.code === -23501 && /not registered/i.test(res.error.message)) {
  // type known to reflection but not initialized in the world -> app-side fix needed
  reportNeedsInitResource(path);
}

Prevention

When it happens

Trigger: Sending `world.insert_resource` with a type path that is registered for reflection but was never initialized in the target World — e.g. no `init_resource::<T>()` / prior insertion exists on the app being inspected.

Common situations: Trying to remotely create a brand-new resource type that the app never declared; app built with `default-features = false` or a minimal plugin set so the resource isn't initialized; type path spelling almost right (deserialization found the type, so this is specifically the world-registration step that failed).

Related errors


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