A bit more for additional clarification:
You as host, have a PlayerState. I as a client have a PlayerState. These are both replicated. Therefore we would both have 2 playerstates on either of our machines. One is mine, one is yours, but in total there are 4 that exist - your 2 copies and my 2 copies, but one for each player in the game.
You as host, have a PlayerController. I as a client have a PlayerController. PlayerControllers are only replicated to the owning client. As host, you must see mine as you're the one in control of the game, so you have 2 PlayerControllers, one for me, one for you. I as a client however, only receive my PlayerController, and if I try to reference yours, I don't have a reference to it as it's not replicated to me. In total there will be 3 copies of the PlayerController, 2 that exist on your computer, one for me and one for you, and I have only 1 on my computer which is my PlayerController.
So if I receive instructions to run "Update Inventory" on your PlayerState, which would happen if your OnRep triggers because the inventory value on your PlayerState changed and you call the "UpdateInventory" event in your OnRep, when I attempt to get your PlayerController from your PlayerState, I have nothing available about your PlayerController, so casting nothing to BP_PlayerController = failed cast.
You as host however, also receive instructions to run "Update Inventory" the same way, but in your case, since you are in control of the game and you have a copy of my PlayerController, when you do GetPlayerController on my playerstate, you can still get a reference to my PlayerController as it exists on your end.