Quick answer: An IAspect struct must be declared partial, contain only RefRO, RefRW, EnabledRefRO, EnabledRefRW, or other aspects, and the source generator must run after compile errors are cleared. If any field is a plain component value or the struct is not partial, the aspect quietly fails to register.

Here is how to fix Unity ECS aspects that fail to register and never appear in your queries. You define an IAspect struct that bundles several components, write a system that iterates with SystemAPI.Query<MyAspect>, and the foreach body never runs. No errors. No warnings. Aspects rely on Roslyn source generators, and the generators have strict requirements that fail silently when violated.

The Symptom

Your aspect declaration compiles. Your system compiles. SystemAPI.Query<TAspect> returns zero results even though entities with the relevant components clearly exist in the world. The Entities Hierarchy window shows the components on those entities, but the query body never executes.

What Causes This

Struct is not partial. Source generators emit additional methods into the aspect type. Without partial, the generated code cannot be merged with your declaration and the aspect type ends up incomplete or not generated at all.

Fields are concrete components, not refs. Aspects do not hold component values; they hold refs. A field of type Translation is invalid; you need RefRW<LocalTransform> or RefRO<LocalTransform>.

Aspect references missing components. If your aspect requires RefRO<Health> but no entity has Health attached, the query matches zero entities. The aspect itself is registered fine, but no entity satisfies it.

Compile errors elsewhere block source generation. Unity’s source generators do not run if the assembly already has compile errors. A red squiggle in another file can prevent your aspect from being generated, even if the aspect itself is valid.

The Fix

Step 1: Mark the struct as partial.

using Unity.Entities;
using Unity.Transforms;

public readonly partial struct PlayerMoveAspect : IAspect
{
    public readonly Entity Self;
    public readonly RefRW<LocalTransform> Transform;
    public readonly RefRO<MoveSpeed> Speed;
    public readonly RefRW<Health> Health;
}

Note partial, readonly, and that every field is a ref type or Entity. Do not include plain LocalTransform fields.

Step 2: Use the aspect in a system.

using Unity.Entities;

public partial struct PlayerMoveSystem : ISystem
{
    public void OnUpdate(ref SystemState state)
    {
        float dt = SystemAPI.Time.DeltaTime;

        foreach (PlayerMoveAspect aspect in SystemAPI.Query<PlayerMoveAspect>())
        {
            aspect.Transform.ValueRW.Position +=
                new Unity.Mathematics.float3(1, 0, 0) * aspect.Speed.ValueRO.Value * dt;
        }
    }
}

Step 3: Make optional components actually optional. If some entities have Health and others do not, use EnabledRefRO or split into a separate aspect.

public readonly partial struct DamageableAspect : IAspect
{
    public readonly RefRW<LocalTransform> Transform;
    public readonly EnabledRefRW<Health> Health;  // Optional / toggle-enabled
}

Step 4: Force a regeneration if changes do not apply. After fixing compile errors elsewhere, switch focus away from Unity and back. The Entities source generator runs again. If it does not, right-click the assembly definition and choose Reimport.

Step 5: Confirm components exist on entities. Open the Entities Hierarchy and select an entity that should match. Verify it has every component the aspect requires. A single missing component means zero matches.

Verifying the Aspect Compiles

Aspects generate hidden helper code. After saving, open Edit → Preferences → Entities → Show Entities In Hierarchy to confirm baking ran. Use the Entities Journaling tool to inspect what queries match what entities. If the aspect type does not appear in autocomplete in SystemAPI.Query<...>, the source generator did not produce it.

“Partial struct, ref fields only, optional components are EnabledRef. Three rules and Roslyn does the rest.”

Related Issues

For empty queries with the right components present, see Entity Query Returning Empty. For tag component issues, see Entity Query Missing Tag.

When the foreach body never runs, the aspect did not generate. Check partial. Check refs.