bevyengine/bevy · error

The collection in RelationshipTarget must be private to prev

Error message

The collection in RelationshipTarget must be private to prevent users from directly mutating it, which could invalidate the correctness of relationships.

What it means

Compile-time error from derive_relationship_target: the field holding the RelationshipTarget's entity collection is not private. Visibility must be inherited because direct user mutation could break relationship invariants that the derive maintains through its hooks.

Source

Thrown at crates/bevy_ecs/macro_logic/src/component.rs:479

        let Some(relationship_target) = &self.relationship_target else {
            return Ok(None);
        };

        let Data::Struct(DataStruct {
            fields,
            struct_token,
            ..
        }) = &ast.data
        else {
            return Err(syn::Error::new(
                ast.span(),
                "RelationshipTarget can only be derived for structs.",
            ));
        };
        let field = relationship_field(fields, "RelationshipTarget", struct_token.span())?;

        if field.vis != Visibility::Inherited {
            return Err(syn::Error::new(field.span(), "The collection in RelationshipTarget must be private to prevent users from directly mutating it, which could invalidate the correctness of relationships."));
        }
        let collection = &field.ty;
        let relationship_member = field.ident.clone().map_or(Member::from(0), Member::Named);

        let members = fields
            .members()
            .filter(|member| member != &relationship_member);

        let relationship = &relationship_target.relationship;
        let struct_name = &ast.ident;
        let (impl_generics, type_generics, where_clause) = &ast.generics.split_for_impl();
        let linked_spawn = relationship_target.linked_spawn;
        let fqdefault = FQDefault.into_token_stream();
        Ok(Some(quote! {
            impl #impl_generics #bevy_ecs::relationship::RelationshipTarget for #struct_name #type_generics #where_clause {
                const LINKED_SPAWN: bool = #linked_spawn;
                type Relationship = #relationship;
                type Collection = #collection;

View on GitHub (pinned to 396ca72708)

Solutions

  1. Make the collection field private (no pub/pub(crate))
  2. Expose read-only access via methods on the RelationshipTarget type
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at crates/bevy_ecs/macro_logic/src/component.rs:479 when the library encounters an invalid state.

Common situations: See trigger scenarios.


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