I’m not sure which APIs are recommended to use with 1.12.2-7.1.5 spongevanilla, but I have confirmed your bug on the 7.1.0 SpongeAPI as well. I made the listeners listen only for @Root Player activity to cut down on noise.
The ops protected area ‘is fine’ because the system cancels block change events and wont even generate the events.
If a reporter is included in the event listener, and the event is cancelled, then the log will spam the block place event 100 times, without cancelling it, and then spew out the phase-error message.
If the transaction is made invalid, instead of cancelling the event, the result is still the same - the event is reported 100 times, however the rail placement IS prevented, but it also spews out the phase-error message.
This is definitely a sponge bug to report in Github, for whatever it is worth for this version.
There isn’t much of a workaround for this problem - sure, you can setValid(false) the transaction for rail placement, instead of just cancelling the event, and that will work, but you will still have the log spammed with errors each time.
The alternative for you FOR NOW might be to check the player-interact-block event, for secondary-interaction, and if they have rails in their hand, prevent the interaction. That will prevent them from being able to place the rails on a block in the first place. The side effect is that they won’t be able to hold rails while opening a chest or dispenser, or maybe a crafting table.
Check in the interact-block event if they are secondary-interacting with any of the types of rails that cause this phase-error to appear. If they are, then apply whatever logic you have for checking their region, and cancel the event here if possible . It will stop rail placement from happening further upstream, and won’t generate a block-place event at all to worry about.
BUT, if they are okay for being able to place rails, then the interact isn’t cancelled, and the block-place will be generated. So make sure to test if they are placing rails in the block-place event first, and if they are, then just allow the event to occur (because you already determined they are in an okay area). For ALL OTHER block placements, do your region-check in the block-place event, and cancel those.
That way you won’t be cancelling or invalidating the block-place event with rails, and causing the server to get stuck in a loop.