Hmm. Well, that sounds like the guild roster API just hadn't updated for the promotion yet, and still returned the old rank, so the code tried to promote him again, which failed because he was actually already at the rank it tried to promote him to. The same thing happens if, for example, you try to call zone info APIs while crossing a zone boundary but before the appropriate event fires -- but since while the animation loop is running, you're not listening for GUILD_ROSTER_UPDATE events, you don't know when the event fires. That actually wasn't what I had in mind when I included the failure protection, but turns out to be a really good reason to have that protection in there.