EntityCommandBufferSystem not removing component until next frame - expected behavior?

I’ve noticed some unexpected behavior with EntityCommandBufferSystem and wanted to confirm if this is normal?

Here’s a simplified version of my code where two systems are interacting with the same component:

 // System 1: Adds component (verified to only run once per entity)
 [BurstCompile]
 private struct AddHeightDataComponentJob : IJob {
     public EntityCommandBuffer CommandBuffer;
     public Entity TargetEntity;

     public void Execute() {
         // Does some stuff with the chunk
         CommandBuffer.AddComponent<ChunkNeedsReRender>(TargetEntity);
         Debug.Log($"Adding for entity: {TargetEntity.Index} : {TargetEntity.Version}");
     }
 }
 // System 2: Removes component
 protected override void OnUpdate() {
     var ecb = SystemAPI.GetSingleton<EndSimulationEntityCommandBufferSystem.Singleton>()
         .CreateCommandBuffer(World.Unmanaged);

     foreach ((RefRO<ChunkCoordinateData> chunkCoordinateData, Entity entity) in
         SystemAPI.Query<RefRO<ChunkCoordinateData>>()
         .WithAll<HasChunkHeightData, ChunkNeedsReRender>()
         .WithEntityAccess())
     {
	// do some stuff with the entity
         ecb.RemoveComponent<ChunkNeedsReRender>(entity);
     }
 }

Both systems run in InitializationSystemGroup and queue changes to EndSimulationEntityCommandBufferSystem.

System 1 is guaranteed to only add the component once per entity and never again (verified through logs and other safety mechanisms).
Despite this, System 2 sometimes sees and processes the same entity twice across different frames, even though it’s queuing the component removal via ECB.

Expected Behavior: When System 2 queues a component removal via ECB, I expect EndSimulationEntityCommandBufferSystem to execute all commands at the end of the frame, meaning the component should be gone by the next frame.

Actual Behavior: Some entities (different amount every test) get processed twice in system 2. I’ve verified this by tracking processed entities:

 if (test.Contains(entity)) {
     Debug.Log($"Entity {entity.Index} being processed again");
 }
 test.Add(entity);

Interestingly, when I switch to using EndInitializationEntityCommandBufferSystem instead (so the same as where the systems are), the issue no longer occurs.

Reproduction of this error is totally unreliable. Some runs it happens other times it doesn’t happen at all for a couple of runs.

I know i should be using Enableable components to avoid structural changes all together but still, I find this behaviour weird?

Is this expected?

Oh also this does not happen if i just create a ECB and play it back in system 2

Basically I want to know if it is guaranteed that when i queue something to a ECB i get from a ECBSystem, that the structural change happens when that ECBSystem is executed (syncpoint)? Or could it be that when there are a lot of changes they get distributed across multiple frames?

It’s guaranteed, there is no such feature

Okay good, that was my assumption.
Strange that i’m seeing this behaviour then…
I can’t be the first person running into this?
I guess ill try and make a mini project to reproduce this.

Okay, i can’t reproduce this in a simple project…
I removed Netcode for Entities and now it doesn’t happen anymore…

It was probably just user error on my part.