Quoting from a similar post i found on reddit:
So, as a programming nerd i am, in my speculation it's about threadlocking and action synchronizing.
All player's input action has to be send to the server (in this case, the host player) and return back to the client (player). There's no loss if you are the host because it takes almost absolutely no time for the action to return as action outputs in your game.
But if you're the client and experiencing network issue, it might take a while to send that action to the host and let it came back as output in your game. By the time the action input of yours returned as output in your screen, the action's duration is already done, thread closes and your game outputs a dead action. So it stucks as a "loop" or "exception", and here you go the infamous "Ability is in use" bug.
I think it's best to sum this up by me expressing it as a string of java code:
server.accept(ability); //server register the action
//some wait time as the server accepting the action and go back to the client
client.register(ability); //sometime server already casting the ability so the client just calling a dead thread
float duration = ...;
thread.close(); //remove ability casting when it finishes its duration