Since the end-of-song callback performs asynchronously with the now-playing-update one, what seems to sometimes happen is that the now-playing callback starts executing and sees that there is a current song. Then, it gets interrupted by the end-of-song callback which sets the current song to None if there are no more songs left in the queue. The now-playing callback resumes, but now the current song is None which causes a TypeError when its attributes are accessed.
Since the end-of-song callback performs asynchronously with the now-playing-update one, what seems to sometimes happen is that the now-playing callback starts executing and sees that there is a current song. Then, it gets interrupted by the end-of-song callback which sets the current song to None if there are no more songs left in the queue. The now-playing callback resumes, but now the current song is None which causes a TypeError when its attributes are accessed.