IF NOT EXISTS doesn't attempt to be bulletproof: it just checks at the start of the command to see if the object name is already there. So it's not sufficient to guard concurrent creations. You can call that a bug if you like, but it's quite unlikely to change anytime soon.
This is then at least a documentation bug since docs provide less information for the user then it's needed to properly decide on strategy.
You might consider using advisory locks [1] to keep your various sessions from trying to do this at the exact same time.
Thanks, I'll update the DDLs to wrap the queries emitted with those locks.