I looked into this more. I was wrong in thinking the posts page was showing fine – it wasn't.

This looks like it indeed an API or DB bug; the post ID I'm using as my tester is one where the thread for it doesn't actually include the post itself, but stops before it!

IIRC parent and root are populated in the post data, so the info should be there to build the thread properly still.