After a chat with pieterh and minrk on #zeromq, we found the cause.
ctx.destroy()
in 13.1.0 has an indentation bug so it only calls Context.term()
if there is an unclosed socket.
Workaround: call ctx.term()
instead, and make sure all of your sockets are closed before you do.